Hola amigos.
estoy haciendo un juego de plataformas... tengo un problema con el escenario... que yo le pongo un escenario y un mapa de clisiones para un nivel...
el mapa de colisiones funciona pero el de la vista no... se me repite en un trozo... me gustaria que me echaran una mano... gracias.
Un saludo
este es el codigo
librerias de palib..
// Includes, only one sprite
#include <PA9.h>
#include <stdio.h>
// PAGfxConverter Include
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
//my includes
#define levellength 256
#define levelheight 32
#define norm_fix(x) ((x)<<8)
#define fix_norm(x) ((x)>>8) //xxx truncates instead of rounds
#define fix_mult(x,y) (((x)*(y))>>8)
#define ratio_fix(x,y) ((256*(x))/(y))
#define fixed_fraction(x) ((x)&&0xff)
#define GRAVITY 60
#define MARIO_SPEED 512
#define maxcoins 70
#define maxuniqueobj 10
#define maxlevels 10
typedef struct objectinfo objectinfo;
typedef struct objectdata objectdata;
typedef struct pointinfo pointinfo;
typedef struct levelinfo levelinfo;
void splash();
void menu();
void MoveMario(void);
void scroll();
void CheckCollisions(void);
void placecoins();
void newobject(s32,s32, objectinfo*, objectdata*);
void objectscroll(objectinfo*);
u8 GetTile(s16, s16);
u8 anycollision(u8, objectinfo*);
u8 TouchingGround(void);
u8 TileCollision(pointinfo*, u8,s32, s32);
u8 tilecollsion(s32,s32,u8,u8);
u8 allcollision();
u8 boxcollision(s32,s32,u8,u8);
u8 getsprite();
u8 getobject();
void deletesprite(objectinfo*);
void createsprite(objectinfo*);
void coincollision(objectinfo*);
void badycollision(objectinfo*);
void simpleai(objectinfo*);
void noai(objectinfo*);
void loadlevel(levelinfo*);
void clearobjects();
u64 arrayadderupper(const unsigned char* , u32 );
struct pointinfo{
s8 x, y, flipx;
};
typedef struct{
pointinfo left, right, up, down;
u8 flipped;
}hitboxinfo;
typedef struct{
u8 layer;
const unsigned char* tiles;
const unsigned short* palette;
const unsigned short* map;
u16 height, width;
u32 size;
} backgroundinfo;
struct levelinfo{
backgroundinfo back[3];
const unsigned short* collisionmap;
};
struct objectinfo{
void (*ai)(objectinfo*);
void (*scroll)(objectinfo*);
void (*collision)(objectinfo*);
hitboxinfo hitbox;
s32 x,y;
u8 h,w;
s32 vy;
s8 sprite;
u8 lastframe;
u8 alive;
const u8* spriteimage;
u8 pallete;
u8 size;
s8 variables;
};
struct objectdata{
void (*ai)(objectinfo*);
void (*scroll)(objectinfo*);
void (*collision)(objectinfo*);
const u8* spriteimage;
u8 h,w;
u8 lastframe;
u8 pallete;
u8 size;
hitboxinfo hitbox;
u8 variables;
s16 tile;
};
typedef struct{
objectinfo info;
s64 vy; // used for jumping...
s64 scrollx, scrolly; // Scroll value...
u8 jumping;
}mariotype;
mariotype mario;
//pointer to items
//pointer to enemies
u8 sprite[128];
u8 objectused[128];
u8 currentlevel;
objectinfo coin[maxcoins];
objectdata data[maxuniqueobj];
levelinfo level[maxlevels];
// Main function
u64 mariosize;
u64 speed=256;
u8 alive=1;
int main(void) {
// PAlib init
PA_Init();
PA_InitVBL();
PA_InitText(1, 0);
//level data
level[0].collisionmap=level1collision_Map;
level[0].back[1].tiles=level1_Tiles;
level[0].back[1].map=level1_Map;
level[0].back[1].palette=level1_Pal;
level[0].back[1].height=32; level[0].back[1].width=256;
level[0].back[1].size=8192;
level[0].back[2].tiles=0;
level[0].back[2].map=0;
level[0].back[2].palette=hills_Pal;
level[0].back[2].height=32; level[0].back[2].width=96;
level[0].back[2].size=2496;
level[0].back[3].tiles=back_Tiles;
level[0].back[3].map=back_Map;
level[0].back[3].palette=back_Pal;
level[0].back[3].height=32; level[0].back[3].width=64;
level[0].back[3].size=4000;
PA_LoadSpritePal(0, 0, (void*)sprite0_Pal); // Palette....
//PA_LoadPal(PAL_BG01,mario_world_Pal);
currentlevel=0;
PA_InitParallaxX(0, 0, 256, 128, 64);
PA_InitParallaxY(0,0,256,128,64);
int i;
for(i=0;i<maxcoins;i++){
coin[i].x=-1;
coin[i].y=-1;
coin[i].alive=0;
coin[i].sprite=-1;
}
for(i=0;i<maxuniqueobj;i++){
data[i].tile=-1;
}
//set up the coin data
data[0].spriteimage=coin_Sprite;
data[0].lastframe=0;
data[0].pallete=0;
data[0].size=0;
data[0].ai=&noai;
data[0].scroll=&objectscroll; //set the scroll method of the coin
data[0].collision=&coincollision;
data[0].hitbox.right.x=8; data[0].hitbox.right.y=4;
data[0].hitbox.left.x=0; data[0].hitbox.left.y=4;
data[0].hitbox.up.x=4; data[0].hitbox.up.y=0;
data[0].hitbox.down.x=4; data[0].hitbox.down.y=8;
data[0].tile=4;
//set up the goomba data
data[1].spriteimage=enemy1_Sprite;
data[1].lastframe=1;
data[1].pallete=0;
data[1].size=1;
data[1].ai=&simpleai;
data[1].scroll=&objectscroll; //set the scroll method of the coin
data[1].collision=&badycollision;
data[1].variables=1;
data[1].hitbox.right.x=16; data[1].hitbox.right.y=8;
data[1].hitbox.left.x=0; data[1].hitbox.left.y=8;
data[1].hitbox.up.x=8; data[1].hitbox.up.y=0;
data[1].hitbox.down.x=8; data[1].hitbox.down.y=16;
data[1].tile=5;
mario.info.x = norm_fix(60); mario.info.y = norm_fix(128-32); // bottom of the screen... fixed point
mario.vy = 0; // not jumping
mario.info.hitbox.flipped=0;
mario.scrollx = 0;
mario.info.pallete=0;
mario.info.spriteimage=player_Sprite;
mario.info.size=2;
mario.info.hitbox.left.x=0; mario.info.hitbox.left.y=11; mario.info.hitbox.right.x=23; mario.info.hitbox.right.y=11; mario.info.hitbox.down.x=11; mario.info.hitbox.down.y=23; mario.info.hitbox.up.x=11; mario.info.hitbox.up.y=0;
mario.info.hitbox.left.flipx=0; mario.info.hitbox.right.flipx=0; mario.info.hitbox.up.flipx=0; mario.info.hitbox.down.flipx=0;
//createsprite(&mario.info); // Sprite
//mariosize=arrayadderupper(&mario_Sprite[0],3072);//debugging
PA_WaitForVBL();
createsprite(&mario.info);
loadlevel(&level[0]);
placecoins();
while(1)
{
while(alive){
MoveMario();
scroll();
//PA_OutputText(1,1,1,"sprite %d %d ",mario.info.x, mario.info.y);
//while(mariosize != arrayadderupper(&mario_Sprite[0],3072));
PA_WaitForVBL();
}
}
return 0;
}
void MoveMario(void){
//testing purposes
if(Pad.Newpress.Up){
speed+=10;
}
if(Pad.Newpress.Right) {
//PA_StartSpriteAnim(0, 0, 0, 1, 6);
//PA_SetSpriteHflip(0, 0, 0);
mario.info.hitbox.flipped = 0;
}
else if(Pad.Newpress.Left) {
//PA_StartSpriteAnim(0, 0, 0, 1, 6);
//PA_SetSpriteHflip(0, 0, 1);
mario.info.hitbox.flipped = 1;
}
if ((Pad.Newpress.A) && (TouchingGround())){ // If pressed A and not in the air
mario.vy = -1500; // Start jumping
mario.jumping=true;
}
if(mario.jumping && !Pad.Held.A && mario.vy<-400){
mario.vy=-400;
}
// Moving Code
mario.info.x += (Pad.Held.Right - Pad.Held.Left)*fix_mult(MARIO_SPEED,speed); // in fixed point...
// Add gravity
if(!TouchingGround()){
mario.vy += fix_mult(GRAVITY,speed);
}
mario.info.y += fix_mult(mario.vy,speed);
CheckCollisions();
if (!TouchingGround()) ; //PA_SetSpriteAnim(0, 0, 2); // Not on the ground
else if(!((Pad.Held.Left)||(Pad.Held.Right))) ; //PA_SetSpriteAnim(0, 0, 0);// Image if not in the air and not walking
}
void scroll(){
if (((fix_norm(mario.info.x-mario.scrollx)) > 130) && (fix_norm(mario.info.x) < 2048-128)){ // Scroll more...
mario.scrollx = mario.info.x - norm_fix(130);
}
else if ((((mario.info.x-mario.scrollx)>>8) < 64) && ((mario.info.x>>8) > 64)){
mario.scrollx = mario.info.x - norm_fix(64);
}
if (((fix_norm(mario.info.y-mario.scrolly)) > 130) && (fix_norm(mario.info.y) < 196)){ // Scroll more...
mario.scrolly = mario.info.y - norm_fix(130);
}
else if ((((mario.info.y-mario.scrolly)>>8) < 90) && ((mario.info.y>>8) > 90)){
mario.scrolly = mario.info.y - norm_fix(90);
}
/*
//automatic scrolling
if(fix_norm(mario.scrollx)+256<levellength*8){
mario.scrollx+=fix_mult(ratio_fix(1,1),speed);
}
*/
// mario.scrolly+=ratio_fix(1,2);
PA_ParallaxScrollXY(0, fix_norm(mario.scrollx),fix_norm(mario.scrolly));
//move player
PA_SetSpriteXY(0, mario.info.sprite, fix_norm(mario.info.x-mario.scrollx), fix_norm(mario.info.y-mario.scrolly));
u16 i;
for(i=0;i<maxcoins;i++){
//scroll all the coins
if(coin[i].alive){
(coin[i].scroll)(&coin[i]);
if(coin[i].sprite!=-1){
(coin[i].ai)(&coin[i]);
}
//PA_OutputText(1,1,i,"x:%d, y:%d",fix_norm(coin[i].x), fix_norm(coin[i].y));
}
}
//PA_OutputText(1, 2, 11, "X : %d ", fix_norm(mario.x));
//PA_OutputText(1, 2, 10, "Y : %d ", mario.y);
//PA_OutputText(1, 2, 12, "Scroll : %d ", fix_norm(mario.scrollx));
}
u8 GetTile(s16 x, s16 y){
//if (y > fix_norm(mario.scrolly)+192) return 1; //collide with bottom
//if (y < fix_norm(mario.scrolly)) return 1; //collide with top
return level[0].collisionmap[((y>>3)*levellength) + (x>>3)];
}
//check for a collision with a tile at pointx, pointy, and adding in flipx if the sprite is flipped
u8 TileCollision(pointinfo* point, u8 flipped, s32 x, s32 y){
return (GetTile(fix_norm(x)+point->x + (flipped*point->flipx), fix_norm(y)+point->y));
}
//checks if mario is on the ground
u8 TouchingGround(void){
return GetTile((fix_norm(mario.info.x))+11 + (mario.info.hitbox.flipped*0), (fix_norm(mario.info.y))+24);
}
//checks if any of the collisions are true for that tile and returns what side
u8 anycollision(u8 tile, objectinfo* object){
if(TileCollision(&object->hitbox.left, object->hitbox.flipped, object->x, object->y)==tile)return 1;
if(TileCollision(&object->hitbox.right, object->hitbox.flipped, object->x, object->y)==tile)return 2;
if(TileCollision(&object->hitbox.up, object->hitbox.flipped, object->x, object->y)==tile)return 3;
if(TileCollision(&object->hitbox.down, object->hitbox.flipped, object->x, object->y)==tile)return 4;
else return 0;
}
u8 boxcollision(s32 x2, s32 y2, u8 h2, u8 w2){
if ( (fix_norm(mario.info.x)>fix_norm(x2)+w2) || (fix_norm(mario.info.x)+18<fix_norm(x2)) ||
(fix_norm(mario.info.y)>fix_norm(y2)+h2) || (fix_norm(mario.info.y)+18<fix_norm(y2)) ){
return 0;
}
else{
return 1;
}
}
s8 getsideboxcollision(s32 x2, s32 y2, u8 h2, u8 w2){
if( fix_norm(mario.info.y)+30>fix_norm(y2) &&
fix_norm(mario.info.x)+30>fix_norm(x2) &&
fix_norm(mario.info.x) <fix_norm(x2)+w2 ){
return 1;
}
return 0;
}
//checks if anything has collided with the player
// tile 1 is solid ground tile 2 is ground that you can stand on but go through
void CheckCollisions(void){
while(anycollision(1, &mario.info)==1 || fix_norm(mario.info.x)+7<fix_norm(mario.scrollx) ){ // Collision on the left of the sprite...
mario.info.x+= norm_fix(1); // Move by 1 pixel...
}
while(anycollision(1, &mario.info)==2){ // Collision on the right of the sprite...
mario.info.x-= norm_fix(1); // Move by 1 pixel...
if(fix_norm(mario.info.x)+7<fix_norm(mario.scrollx)){ //mario is squashed
//mario is dead
alive=0;
}
}
while(anycollision(1,&mario.info)==3 || fix_norm(mario.info.y)<-20){ // Collision with the something on top
mario.info.y+=norm_fix(1);
mario.vy=0;
}
while(anycollision(1,&mario.info)==4 || anycollision(2,&mario.info)==4){ // Collision on the bottom of the sprite...
mario.info.y -= ratio_fix(1,2); // Move by 1/2 pixel...
}
if( (TouchingGround()==1 || TouchingGround()==2) && mario.vy>0){ //if he's touching the ground and moving down he can't hit ground while moving up
mario.vy = 0;
mario.info.y += norm_fix(2);
mario.jumping=0;
}
if(anycollision(3,&mario.info) && fix_norm(mario.info.y) > 0){
alive=0;
}
//coin collisions
int i;
for(i=0;i<maxcoins;i++){
if(coin[i].sprite!=-1 && coin[i].alive){
//coincollision(&coin[i]);
(coin[i].collision)(&coin[i]);
}
}
}
//places coins whenever it finds yellow
void placecoins(){
int i;
int j;
int k;
for(i=0;i<levellength;i++){
for(j=0;j<levelheight;j++){
for(k=0;k<maxuniqueobj;k++){
if(GetTile(i*8,j*8)==data[k].tile){
newobject(i*8,j*8, &coin[getobject()], &data[k]);
}
}
}
}
}
void newobject(s32 x, s32 y, objectinfo* object, objectdata* data){
object->spriteimage=data->spriteimage;
object->lastframe=data->lastframe;
object->pallete=data->pallete;
object->size=data->size;
object->ai=data->ai;
object->x=norm_fix(x);
object->y=norm_fix(y);
object->alive=1;
object->sprite=-1;
object->scroll=data->scroll; //set the scroll method of the coin
object->hitbox=data->hitbox;
object->collision=data->collision;
object->variables=data->variables;
}
void objectscroll(objectinfo* mover){
//check if coin is onscreen
if(fix_norm(mover->x)<=fix_norm(mario.scrollx)+256 && fix_norm(mover->x)>=fix_norm(mario.scrollx)-8){
//if it is then move it to the correct position
if(mover->sprite!=-1){
PA_SetSpriteXY(0,mover->sprite,fix_norm(mover->x)-fix_norm(mario.scrollx),fix_norm(mover->y)-fix_norm(mario.scrolly));
}
//if it's not then create a sprite for it
else{
createsprite(mover);
PA_SetSpriteXY(0,mover->sprite,fix_norm(mover->x)-fix_norm(mario.scrollx),fix_norm(mover->y)-fix_norm(mario.scrolly));
}
}
//if the coin is offscreen delete it
else{
//don't delete already gone stuff
if(mover->sprite!=-1){
deletesprite(mover);
}
}
}
u8 getsprite(){
int i;
for(i=0;i<128;i++){
if(sprite[i]==0){
sprite[i]=1;
return i;
}
}
return -1;
}
u8 getobject(){
int i;
for(i=0;i<128;i++){
if(objectused[i]==0){
objectused[i]=1;
return i;
}
}
return -1;
}
void deletesprite(objectinfo* todelete){
sprite[todelete->sprite]=0;
PA_DeleteSprite(0,todelete->sprite);
PA_StopSpriteAnim(0,todelete->sprite);
todelete->sprite=-1;
}
void createsprite(objectinfo* todraw){
todraw->sprite=getsprite();
PA_CreateSprite(0, todraw->sprite,todraw->spriteimage, 0,todraw->size,1, todraw->pallete, fix_norm(todraw->x), fix_norm(todraw->y));
if(todraw->lastframe)PA_StartSpriteAnim(0,todraw->sprite,0,todraw->lastframe,6);
}
void loadlevel(levelinfo* toload){
int i;
for(i=1;i<4;i++){
PA_LoadBgPal(0,i,toload->back[i].palette);
PA_LoadLargeBg(0,i,toload->back[i].tiles,level[0].back[i].map,1,toload->back[i].width,toload->back[i].height);
PA_LoadBgTilesEx(0,i,toload->back[i].tiles,toload->back[i].size);
}
mario.info.x = norm_fix(60); mario.info.y = norm_fix(128-32); // bottom of the screen... fixed point
mario.vy = 0; // not jumping
}
void clearobjects(){
int i;
for(i=0;i<maxcoins;i++){
coin[i].x=0;
coin[i].y=0;
coin[i].vy=0;
coin[i].sprite=-1;
coin[i].alive=0;
coin[i].variables=0;
}
for(i=0;i<128;i++){
sprite[i]=0;
objectused[i]=0;
}
PA_ResetSpriteSys();
mario.info.x = norm_fix(60); mario.info.y = norm_fix(128-32); // bottom of the screen... fixed point
mario.vy = 0; // not jumping
mario.info.hitbox.flipped=0;
mario.scrollx = 0;
mario.info.pallete=0;
mario.info.spriteimage=player_Sprite;
mario.info.size=2;
mario.info.hitbox.left.x=0; mario.info.hitbox.left.y=11; mario.info.hitbox.right.x=23; mario.info.hitbox.right.y=11; mario.info.hitbox.down.x=11; mario.info.hitbox.down.y=23; mario.info.hitbox.up.x=11; mario.info.hitbox.up.y=0;
mario.info.hitbox.left.flipx=0; mario.info.hitbox.right.flipx=0; mario.info.hitbox.up.flipx=0; mario.info.hitbox.down.flipx=0;
};
void coincollision(objectinfo* object){
if(boxcollision(object->x,object->y,8+object->size*8,8+object->size*8)){
object->alive=false;
deletesprite(object);
}
}
void badycollision(objectinfo* object){
if(boxcollision(object->x,object->y,8+object->size*8,8+object->size*8)){
if(fix_norm(mario.info.y)+10<fix_norm(object->y)){
object->alive=false;
mario.vy=-1000;
deletesprite(object);
}
else{
alive=0;
}
}
}
void simpleai(objectinfo* bady){
bady->x+=fix_mult(norm_fix(1)*bady->variables*-1,speed);
bady->vy += fix_mult(GRAVITY,speed);
bady->y += fix_mult(bady->vy,speed);
while(anycollision(1, bady)==1){ // Collision on the left of the sprite...
bady->x+= norm_fix(1); // Move by 1 pixel...
bady->variables=bady->variables*-1;
}
while(anycollision(1, bady)==2){ // Collision on the right of the sprite...
bady->x-= norm_fix(1); // Move by 1 pixel...
bady->variables=bady->variables*-1;
}
while(anycollision(1,bady)==3){ // Collision with the something on top
bady->y+= norm_fix(1);
}
while(anycollision(1,bady)==4 || anycollision(2,bady)==4){ // Collision on the bottom of the sprite...
bady->y -= norm_fix(1); // Move by 1/2 pixel...
bady->vy=0;
}
if(anycollision(3,bady) ){
bady->alive=false;
deletesprite(bady);
}
}
void noai(objectinfo* bady){
}
u64 arrayadderupper(const unsigned char* arraystart, u32 length){
int i;
u64 total=0;
for (i=0;i<length;i++){
total+=arraystart[i];
}
return total;
}
Dios me he mareado, al menos
Dios me he mareado, al menos usa la funcion de código
EDIT: has copiado el code desde la antigua página de palib, o algo similar?
Be Libre my Friend.
la verdad que si
estoy intentando mejorar el ejemplo de palib...
cambiando mario por un player etc...
me podrias decir que es lo que me pasa con el mapa? gracias
No encuentro el fallo, pero
No encuentro el fallo, pero te recomiendo intentar hacer tu, por tu cuenta el juego de plataformas, los ejemplos son para ver como sería, te recomiendo hacerlo de 0 y si eso hazlo con nflib, es mas sencillo, y el ejemplo de plataformas de nflib es mucho mas claro que el de palib
Suerte
Be Libre my Friend.
Da mas detalles, libreria,
Da mas detalles, libreria, código, imagen, sino es imposible, y como diria knightfox: No me funciona la Bola Mágica