Page 3 sur 3

Re: Petit remake d'un Mario sur Atari 7800

Publié : sam. 04/avr./2020 15:47
par G-Rom
je pensais avoir réglé le problème de fuite de mémoire... bizarre que cela m'ai échapper , enfin , merci de le souligné , en regardant de plus près GrabSprite() serais le fautif , c'est vrai que je ne supprime pas le sprite après le flipbuffers , mais même en le faisant , ca ne change rien :/

Re: Petit remake d'un Mario sur Atari 7800

Publié : sam. 04/avr./2020 23:14
par Ollivier

Code : Tout sélectionner

;*****************************************************************************************************************************************************************************************
;
; - Mario Atari 7800 pseudo clone
;             GRom
;

#WAVE_FILE = 0 ; undef this if you dont have sound media

Macro PlaySoundEX(id,flag)
       CompilerIf #WAVE_FILE
              PlaySound(id,flag)
       CompilerEndIf
EndMacro   

RandomSeed( Random($FFFFFF) )

Structure Entity
       SpriteId.l
       X.d
       Y.d
       VX.d
       VY.d
       AnimTime.l
       AnimSpeed.l
       FlipMe.b
       anim_left_min.l
       anim_left_max.l
       anim_right_min.l
       anim_right_max.l
       jumping.b
       jump_height.d
       onground.b
       max_velx.d
       max_vely.d 
       gravity.f
       use_physic.b
       is_ghost.b
       blink.l
       wrap.b
       deleteme.b
EndStructure


Structure Pnj Extends Entity
       jumper.b
       jump_time.l  
       jump_delay.l
       direction.l ; 1 right , 0 left
       entry_mode.l; 1 out ; 0 in
       collide_time.l ; prevent infinite collision
       is_cool.b
EndStructure

Structure Coin Extends Entity
       direction.l ; 1 right , 0 left
       uncollect_time.l ; prevent collect at spawn
EndStructure


Structure Player Extends Entity
       is_die.b  
       freeze_time.l
       invincible.b
       invincible_time.l
       life.l
       next_life.l
       score.l
EndStructure

Structure Missile Extends Entity
       IsFalling.I
       direction.l
EndStructure




Global max_mob = 1
Global mob_spawn_delay
Global speed_factor.f = 1
Global Mario.Player
Global NewList Mob.Pnj()
Global NewList Bonus.Coin()
Global NewList Missile.Missile()

Global ScoreDelta = 50


Mario\x = 8 * 8
Mario\y = (10 * 8) 
Mario\spriteid = 12
Mario\jump_height = 3.8
Mario\animspeed = 50
Mario\anim_right_min = 12
Mario\anim_right_max = 14
Mario\anim_left_min = 18
Mario\anim_left_max = 20
Mario\gravity = 0.2
Mario\use_physic = #True 
Mario\is_die = #False 
Mario\is_ghost = #False 
Mario\invincible = #False 
Mario\Life = 4
Mario\wrap = #True 
Mario\next_life = 3000

Declare.l getcolor(rgb)
Declare draw_value(value.l,x,y)
Declare check_solid(x.d,y.d)
Declare is_solid(tilex,tiley)
Declare spawn_mob()
Declare draw_entity(*e.entity)
Declare update_physic(*e.Entity)
Declare entity_collide(*a.Entity, *b.Entity)
Declare entity_collide_point(*e.entity,x.f,y.f, velocity.b = #False)
Declare spawn_coin(x,y,d)
Declare spawn_missile(y)
Declare draw_missile(*m.Missile)
Declare update_missile(*m.missile)




InitSprite() : InitKeyboard() : InitMouse() : InitSound() : joypad = InitJoystick()
ExamineDesktops()
Global dw = DesktopWidth(0)
Global dh = DesktopHeight(0)
Global deltatime.d = 0

OpenScreen(dw,dh,32,"",#PB_Screen_NoSynchronization)
Global gpu_texture = CreateSprite(#PB_Any,48,48,#PB_Sprite_AlphaBlending)

Global Dim Color.l(16)
CopyMemory(?palette, @Color(), ?end_palette - ?palette) 

Global Dim Texture.b(48*48)
CopyMemory(?texture, @Texture(), ?end_texture - ?texture) 

Global Dim Tilemap.b(19*16)
CopyMemory(?tilemap, @Tilemap(), ?end_tilemap - ?tilemap) 

Global Dim SolidTile.b(?end_solid_tile - ?solid_tile)
CopyMemory(?solid_tile, @SolidTile(), ?end_solid_tile - ?solid_tile) 

Global Dim SubSprite.l(36)

StartDrawing(SpriteOutput(gpu_texture))
For y = 0 To 47
       For x = 0 To 47
              index = x + 48 * y
              Plot(x,y, Color( Texture(index) ) )
       Next
Next
StopDrawing()

Procedure DisplayTransparentSprite_(N, X, Y)
       DisplayTransparentSprite(N, ((DW - DH) / 2) + (X * DH) / 128.0, Y * DH / 128)
EndProcedure


DisplaySprite(gpu_texture,0,0)
For clip = 0 To 35
       x = clip % 6
       y = clip / 6
       SubSprite(clip) = GrabSprite(#PB_Any,x*8,y*8,8,8) 
       TransparentSpriteColor(SubSprite(clip), RGB(255,0,255))
       ZoomSprite(SubSprite(clip), dh / 16, dh / 16) ; <<<<<<<<<<<<<<<<<<<<
Next


CompilerIf #WAVE_FILE
       ;   sound_jump    = LoadSound(#PB_Any,"jump.wav")
       ;   sound_hurt    = LoadSound(#PB_Any,"hurt.wav")
       ;   sound_kill    = LoadSound(#PB_Any,"kill.wav")
       ;   sound_coin    = LoadSound(#PB_Any,"coin.wav")
       ;   sound_fall    = LoadSound(#PB_Any,"falling.wav")
       ;   sound_respawn = LoadSound(#PB_Any,"respawn.wav")
       ;   sound_rejump  = LoadSound(#PB_Any,"rejump.wav")
       ;   sound_missile  = LoadSound(#PB_Any,"missile.wav")
       ;   sound_extralife  = LoadSound(#PB_Any,"extralife.wav")
       
       
       sound_jump    = CatchSound(#PB_Any,?bin_sound_jump, ?bin_sound_jump_e - ?bin_sound_jump)
       sound_hurt    = CatchSound(#PB_Any,?bin_sound_hurt, ?bin_sound_hurt_e - ?bin_sound_hurt)
       sound_kill    = CatchSound(#PB_Any,?bin_sound_kill, ?bin_sound_kill_e - ?bin_sound_kill)
       sound_coin    = CatchSound(#PB_Any,?bin_sound_coin, ?bin_sound_coin_e - ?bin_sound_coin)
       sound_fall    = CatchSound(#PB_Any,?bin_sound_falling, ?bin_sound_falling_e - ?bin_sound_falling)
       sound_respawn = CatchSound(#PB_Any,?bin_sound_respawn, ?bin_sound_respawn_e - ?bin_sound_respawn)
       sound_rejump  = CatchSound(#PB_Any,?bin_sound_rejump, ?bin_sound_rejump_e - ?bin_sound_rejump)
       sound_missile  = CatchSound(#PB_Any,?bin_sound_missile, ?bin_sound_missile_e - ?bin_sound_missile)
       sound_extralife = CatchSound(#PB_Any,?bin_sound_extralife, ?bin_sound_extralife_e - ?bin_sound_extralife)
       
       
       
       
       
       
       
       
CompilerEndIf 


; spawn_missile(14)
missile_timer = ElapsedMilliseconds() + 4000
missile_middle_timer = ElapsedMilliseconds() + 10000

; boucle principale
;
accumulator.d = 0
While #True
       ExamineKeyboard()
       
       deltatime = (ElapsedMilliseconds() - lasttime.d) / 1000
       lasttime = ElapsedMilliseconds()
       accumulator + deltatime
       
       If mob_spawn_delay < ElapsedMilliseconds() And ListSize(Mob()) < max_mob
              mob_spawn_delay = ElapsedMilliseconds() + Random(3000,750)
              spawn_mob()
       EndIf
       
       
       ;
       ;-INPUT
       ;
       If KeyboardPushed(#PB_Key_Escape)
              Break
       EndIf
       
       
       If Mario\is_die = #False 
              
              If joypad
                     If ExamineJoystick(0)
                            joy_axisx = JoystickAxisX(0) 
                            joy_button = JoystickButton(0,3)
                     EndIf
              EndIf 
              
              If KeyboardPushed(#PB_Key_Right) Or joy_axisx = 1
                     Mario\vx = 1
                     Mario\flipme = #False 
              EndIf
              
              If KeyboardPushed(#PB_Key_Left) Or joy_axisx = -1
                     Mario\vx = -1
                     Mario\flipme = #True 
              EndIf
              
              If KeyboardPushed(#PB_Key_Space) Or joy_button = 1
                     Mario\jumping = #True 
                     
                     If sound_jump_flag = 0
                            sound_jump_flag = 1
                            PlaySoundEX(sound_jump,#PB_Sound_MultiChannel)
                     EndIf 
                     
              Else
                     sound_jump_flag = 0
                     Mario\jumping = #False      
              EndIf
              
              If Not (KeyboardPushed(#PB_Key_Right) Or joy_axisx = 1) And Not (KeyboardPushed(#PB_Key_Left)  Or joy_axisx = -1 )
                     Mario\vx = 0    
              EndIf
              
       EndIf 
       
       
       ;-GAME LOGIC
       
       ; Spawn missile
       
       If Mario\y < 32 And missile_timer < ElapsedMilliseconds()
              missile_timer = ElapsedMilliseconds() + 5000
              spawn_missile(Random(2))
              PlaySoundEX(sound_missile,#PB_Sound_MultiChannel)
       ElseIf Mario\y > 32
              missile_timer = ElapsedMilliseconds() + 5000
       EndIf   
       
       If Mario\y > 32 And Mario\y< 96 And missile_middle_timer < ElapsedMilliseconds()
              missile_middle_timer = ElapsedMilliseconds() + 10000
              spawn_missile(Random(10,4))
              PlaySoundEX(sound_missile,#PB_Sound_MultiChannel)
       ElseIf (Mario\y < 32 Or Mario\y > 96)
              missile_middle_timer = ElapsedMilliseconds() + 10000
       EndIf   
       
       
       
       If Mario\score => Mario\next_life 
              Mario\next_life + 3000
              Mario\life + 1
              PlaySoundEX(sound_extralife,#PB_Sound_MultiChannel)
       EndIf 
       
       ; Mario die ( jumping )
       If Mario\is_die And Mario\freeze_time < ElapsedMilliseconds() And Mario\use_physic = #False 
              Mario\use_physic = #True   
              Mario\vy = -Mario\jump_height
              PlaySoundEX(sound_fall,#PB_Sound_MultiChannel)
       EndIf
       
       If Mario\is_die And Mario\y > 2048
              Mario\Life - 1
              If Mario\Life = 0
                     End
              EndIf
              
              Mario\invincible = #True 
              Mario\invincible_time = ElapsedMilliseconds() + 2000
              Mario\x = 8 * 8
              Mario\y = (10 * 8) 
              Mario\vy = 0
              Mario\vx = 0
              Mario\is_ghost = #False 
              Mario\is_die = #False 
              PlaySoundEX(sound_respawn,#PB_Sound_MultiChannel)
       EndIf
       
       
       If Mario\invincible And Mario\invincible_time > ElapsedMilliseconds()
              Mario\blink+1 : Mario\blink%4
       ElseIf Mario\invincible And Mario\invincible_time < ElapsedMilliseconds()
              Mario\invincible = #False 
              Mario\blink = 0
       EndIf 
       
       ForEach(Bonus())
              
              If( entity_collide_point(@Mario,Bonus()\x + 4 , Bonus()\y + 4) ) And Bonus()\uncollect_time < ElapsedMilliseconds()
                     Mario\score + 1000
                     
                     PlaySoundEX(sound_coin,#PB_Sound_MultiChannel)
                     
                     If DeleteElement(Bonus(),1)=0
                            Break
                     EndIf 
                     
              EndIf
              
              If Bonus()\direction = 1
                     Bonus()\vx = 0.5
              Else
                     Bonus()\vx = -0.5
              EndIf
              
              If Bonus()\deleteme
                     DeleteElement(Bonus())
              EndIf    
       Next
       
       
       ForEach(@Mob())
              
              Mob()\vx = 0.2
              
              If Mob()\jumper = #True 
                     If Mob()\jump_time < ElapsedMilliseconds()
                            Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                            Mob()\jumping = #True 
                     Else
                            Mob()\jumping = #False
                     EndIf
              EndIf 
              
              If Mob()\direction = 1
                     Mob()\vx = 0.25
              Else
                     Mob()\vx = -0.25
              EndIf 
              
              
              ; down pipe enter
              ;
              If Round(Mob()\x/8,#PB_Round_Down) = 0 And Round(Mob()\y/8,#PB_Round_Down) = 14 And Mob()\vx < 0
                     Mob()\use_physic = #False 
                     Mob()\entry_mode = 0
                     Mob()\is_cool = #True 
              EndIf
              
              If Round(Mob()\x/8,#PB_Round_Down) = 16 And Round(Mob()\y/8,#PB_Round_Down) = 14 And Mob()\vx > 0
                     Mob()\use_physic = #False 
                     Mob()\entry_mode = 0
                     Mob()\is_cool = #True
              EndIf
              
              
              If Mob()\use_physic = #False 
                     
                     ; down pipe enter move
                     If Mob()\entry_mode = 0
                            If Round(Mob()\y/8,#PB_Round_Down) > 12
                                   Mob()\y - 0.25
                            EndIf 
                            
                            ; left pipe
                            If Mob()\vx < 0 And Round(Mob()\y/8,#PB_Round_Down) = 12
                                   Mob()\x - 0.25
                                   If Round(Mob()\x/8,#PB_Round_Down) = 0
                                          Mob()\x  = 1*8
                                          Mob()\y  = 1*8
                                          Mob()\entry_mode = 1
                                          Mob()\direction = 1
                                          Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                                   EndIf             
                            EndIf 
                            
                            ; right pipe
                            If Mob()\vx > 0 And Round(Mob()\y/8,#PB_Round_Down) = 12
                                   Mob()\x + 0.25
                                   If Round(Mob()\x/8,#PB_Round_Down) = 17
                                          Mob()\x  = 16*8
                                          Mob()\y  = 1*8
                                          Mob()\entry_mode = 1
                                          Mob()\direction = 0
                                          Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                                   EndIf 
                            EndIf 
                     EndIf 
                     
                     ; up pipe exit
                     If Mob()\entry_mode = 1
                            If Mob()\vx > 0
                                   Mob()\x + 0.25  
                                   If Round(Mob()\x/8,#PB_Round_Down) = 1 : Mob()\use_physic = #True : Mob()\is_cool = #False : EndIf
                            EndIf
                            
                            If Mob()\vx < 0
                                   Mob()\x - 0.25 
                                   If Round(Mob()\x/8,#PB_Round_Down) = 15 : Mob()\use_physic = #True : Mob()\is_cool = #False : EndIf
                            EndIf
                            
                     EndIf
              EndIf
              
       Next
       
       
       
       While ( accumulator > 1.0/60.0 )
              ;-PHYSIC
              ;
              
              update_physic(@Mario)
              
              ForEach (Bonus())
                     update_physic(@Bonus())  
              Next
              
              ; collide Mob/Mob , Mob/Mario
              ForEach(Mob())
                     
                     ; mob / mob 
                     *c.Pnj = @Mob()
                     PushListPosition(Mob())
                     ForEach Mob()
                            
                            If @Mob() <> *c And Mob()\collide_time < ElapsedMilliseconds()
                                   If entity_collide(*c,@Mob())
                                          *c\direction + 1 : *c\direction % 2
                                          Mob()\direction + 1 : Mob()\direction %2
                                          Mob()\collide_time = ElapsedMilliseconds() + 250            
                                   EndIf 
                            EndIf 
                            
                     Next
                     PopListPosition(Mob())
                     
                     If Mob()\is_cool = #False 
                            ; mob / mario      
                            If entity_collide(@Mario,@Mob()) And Mario\is_die = #False 
                                   
                                   
                                   If Mario\y < Mob()\y 
                                          
                                          Mario\vy = -(Mario\jump_height/1.1)
                                          
                                          If Random(10) = 0
                                                 spawn_coin(Mob()\x,Mob()\y,(Mob()\direction+1)%2 )
                                          EndIf 
                                          
                                          Mario\score + ScoreDelta
                                          ScoreDelta * 2
                                          
                                          max_mob + 1
                                          If max_mob > 8
                                                 max_mob = 8
                                          EndIf 
                                          
                                          PlaySoundEX(sound_kill,#PB_Sound_MultiChannel)
                                          PlaySoundEX(sound_rejump,#PB_Sound_MultiChannel)
                                          
                                          If DeleteElement(Mob(),1) = 0
                                                 Break   
                                          EndIf 
                                          
                                   ElseIf Mario\y  >= Mob()\y And Mario\invincible = #False 
                                          Mario\vx = 0
                                          Mario\vy = 0
                                          Mario\is_die = #True 
                                          Mario\is_ghost = #True
                                          Mario\freeze_time = ElapsedMilliseconds() + 500
                                          Mario\use_physic = #False
                                          Mario\spriteid = 34
                                          
                                          PlaySoundEX(sound_hurt,#PB_Sound_MultiChannel)
                                          
                                          If Mario\life = 0
                                                 
                                                 spr = GrabSprite(#PB_Any,0,0,dw,dh)
                                                 UsePNGImageEncoder()
                                                 SaveSprite(spr,"MyScore.png",#PB_ImagePlugin_PNG)
                                                 
                                                 End
                                          EndIf
                                          
                                   EndIf 
                            EndIf 
                     EndIf 
                     update_physic(@Mob())
                     
                     
              Next
              
                     
             
              ; missile "physic..."
              ;
              ForEach Missile()
                     update_missile(@Missile())
                     
                            ; mISSILE / mario      
                            If entity_collide(@Mario, @Missile() ) And Mario\is_die = #False 
                                   
                                   
                                   If Mario\y < Missile()\y 
                                          
                                          Missile()\IsFalling = 1
                                          
                                          Mario\vy = -(Mario\jump_height/1.1)
                                          
                                          If Random(10) = 0
                                                 spawn_coin(Missile()\x,Missile()\y,(Missile()\direction+1)%2 )
                                          EndIf 
                                          
                                          ScoreDelta * 2
                                          Mario\score + ScoreDelta
                                          ScoreDelta * 2
                                          
                                   ElseIf Mario\y  >= Missile()\y And Mario\invincible = #False 
                                          Mario\vx = 0
                                          Mario\vy = 0
                                          Mario\is_die = #True 
                                          Mario\is_ghost = #True
                                          Mario\freeze_time = ElapsedMilliseconds() + 500
                                          Mario\use_physic = #False
                                          Mario\spriteid = 34
                                          Mario\life - 1
                                          
                                          PlaySoundEX(sound_hurt,#PB_Sound_MultiChannel)
                                          
                                          If Mario\life = 0
                                                 
                                                 spr = GrabSprite(#PB_Any,0,0,dw,dh)
                                                 UsePNGImageEncoder()
                                                 SaveSprite(spr,"MyScore.png",#PB_ImagePlugin_PNG)
                                                 
                                                 End
                                          EndIf
                                          
                                   EndIf 
                            EndIf 
                     
                     
                     
                     If(Missile()\x < -200 Or Missile()\x > 328) Or Missile()\y > 2048
                            DeleteElement(Missile())
                     EndIf
                     
                     
                     
                     
              Next 
              
              accumulator - (1.0/60.0)
       Wend 
       
       
       ;
       ;-DRAWING
       ;
       
       ClearScreen(RGB(26,28,44))
       
       ; draw mob
       ForEach(Mob())
              draw_entity(@Mob())  
       Next
       
       ForEach (Bonus())
              draw_entity(@Bonus())  
       Next
       
       
       ForEach Missile()
              draw_missile(@Missile())
       Next 
       
       ; draw tilemap
       For y = 0 To 15
              For x = 0 To 17
                     index = x + 19 * y
                     DisplayTransparentSprite_( SubSprite(Tilemap( index )) ,x*8,y*8)
                     
                     ;       
              Next
       Next
       
       ; draw mario
       draw_entity(@Mario)
       
       ; draw score   
       draw_value( Mario\score, (64 - (((Len(Str(Mario\score))-1)*8)/2))+8 ,4)
       ; draw life
       For i = 0 To Mario\Life - 2
              DisplayTransparentSprite_(SubSprite(35),8+(i*8),0)
       Next
       
       DisplayTransparentSprite_(SubSprite(coin_id),(8+128)-8*4,0)
       FlipBuffers()
       Delay(16)
Wend

CloseScreen()
End 



Procedure.l getcolor(rgb)
       For i = 0 To 15
              If Color(i) = rgb
                     ProcedureReturn i
              EndIf
       Next 
EndProcedure



Procedure draw_value(value.l,x,y)
       str$ = Str(value)  
       For i = 0 To Len(str$)-1
              n.l = Val(Mid(str$,i+1,1))
              DisplayTransparentSprite_( SubSprite( 24 + n ) , x + (i * 6),y)
       Next
EndProcedure


Procedure check_solid(x.d, y.d)
       ProcedureReturn is_solid(Round(x/8,#PB_Round_Down),Round(y/8,#PB_Round_Down))
EndProcedure


Procedure is_solid(tilex,tiley)
       index = tilex + 19 * tiley
       If index >= 0 And index < (19*16)
              tile_id = Tilemap(index)
              For i = 0 To (?end_solid_tile - ?solid_tile) - 1
                     If tile_id = SolidTile(i)
                            ProcedureReturn #True
                     EndIf 
              Next
       EndIf 
       ProcedureReturn #False 
EndProcedure


Procedure spawn_mob()
       AddElement(Mob())
       
       
       Mob()\jump_height    = 1.0
       
       If Random(9) > 2 
              Mob()\anim_left_min  = 21
              Mob()\anim_left_max  = 22
              Mob()\anim_right_min = 21
              Mob()\anim_right_max = 22
              Mob()\animspeed      = 25
              Mob()\jumper         = #True 
              Mob()\jump_delay     = 250
       Else 
              Mob()\anim_left_min  = 6
              Mob()\anim_left_max  = 8
              Mob()\anim_right_min = 6
              Mob()\anim_right_max = 8
              Mob()\animspeed      = 100
              Mob()\jumper         = #False
       EndIf 
       
       
       Mob()\gravity        = 0.1  
       Mob()\direction = Random(1)
       Mob()\use_physic = #False
       Mob()\entry_mode = 1
       Mob()\is_ghost = #False 
       Mob()\is_cool = #False 
       Mob()\wrap = #True 
       
       If Mob()\direction = 1
              Mob()\x  = 0
              Mob()\y  = 1*8
       Else
              Mob()\x  = 16*8 
              Mob()\y  = 1*8
       EndIf
       
       
EndProcedure


Procedure spawn_coin(x,y,direction)
       AddElement(Bonus())
       
       Bonus()\jumping = #True 
       Bonus()\jump_height    = 0.5
       
       Bonus()\anim_left_min  = 15
       Bonus()\anim_left_max  = 17
       Bonus()\anim_right_min = 15
       Bonus()\anim_right_max = 17
       Bonus()\animspeed      = 25
       
       Bonus()\gravity        = 0.05
       Bonus()\use_physic = #True
       Bonus()\is_ghost = #False 
       Bonus()\wrap = #True
       Bonus()\x  = x
       Bonus()\y  = y
       Bonus()\direction = direction
       Bonus()\uncollect_time = ElapsedMilliseconds() + 100
       If Bonus()\direction = 1
              Bonus()\vx = 0.5
              Bonus()\vy = -1.0
       Else
              Bonus()\vx = -0.5
              Bonus()\vy = -1.0
       EndIf
       
EndProcedure


Procedure spawn_missile(y)
       AddElement(Missile())
       
       Missile()\use_physic = #False 
       Missile()\direction = Random(1)
       
       If  Missile()\direction
              Missile()\x = - 16
              Missile()\y = y * 8
              Missile()\vx = 1
       Else
              Missile()\x = 128 
              Missile()\y = y * 8
              Missile()\vx = -1
       EndIf
       
       
       
       
EndProcedure

Procedure draw_missile(*m.Missile)
       
       If  Missile()\direction
              DisplayTransparentSprite_( SubSprite(9) , *m\x, *m\y) ; tail
              DisplayTransparentSprite_( SubSprite(4) , *m\x + 8, *m\y) ; head
       Else
              DisplayTransparentSprite_( SubSprite(10) , *m\x+8, *m\y) ; tail
              DisplayTransparentSprite_( SubSprite(11) , *m\x, *m\y)   ; head    
       EndIf
       
       
       
       
EndProcedure

Procedure update_missile(*m.missile)
       If *m\IsFalling
              *m\vx = 0
              *m\vy + 0.2
       EndIf       
       *m\x + *m\vx  
       *m\y + *m\vy
EndProcedure

Procedure draw_entity(*e.entity)
       
       If *e\vx <> 0 And *e\is_ghost = #False 
              
              If ( *e\animtime < ElapsedMilliseconds() )
                     *e\animtime = ElapsedMilliseconds() + *e\animspeed
                     *e\spriteid+1
                     
                     If *e\flipme = #False   
                            If *e\spriteid < *e\anim_right_min : *e\spriteid = *e\anim_right_min : EndIf
                            If *e\spriteid > *e\anim_right_max
                                   *e\spriteid = *e\anim_right_min
                            EndIf       
                     Else 
                            If *e\spriteid < *e\anim_left_max : *e\spriteid = *e\anim_left_max : EndIf
                            If *e\spriteid > *e\anim_left_max
                                   *e\spriteid = *e\anim_left_min
                            EndIf
                     EndIf 
                     
              EndIf
              
       ElseIf *e\vx = 0 And *e\is_ghost = #False 
              If *e\flipme = #False 
                     *e\spriteid = *e\anim_right_min
              Else
                     *e\spriteid = *e\anim_left_min
              EndIf 
       EndIf
       
       If *e\blink = 1 
              DisplayTransparentSprite_( SubSprite(0) , *e\x, *e\y)
       Else
              DisplayTransparentSprite_( SubSprite(*e\spriteid) , *e\x, *e\y)
       EndIf
       
EndProcedure



Procedure update_physic(*e.Entity)
       
       If *e\use_physic
              
              
              ; side collision
              If check_solid( *e\x + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + 7 + *e\vy) Or check_solid( *e\x + *e\vx, *e\y + 7 + *e\vy)
                     *e\vx = 0
              EndIf 
              
              ; collision down
              If (check_solid( *e\x , *e\y + 8 + *e\vy) Or check_solid( *e\x + 7 , *e\y + 8 + *e\vy)) And *e\is_ghost = #False 
                     *e\vy = 0
                     *e\onground = #True
                     If *e = @Mario
                            ScoreDelta = 50
                     EndIf

              Else
                     *e\vy = *e\vy + *e\gravity ; falling
                     *e\onground = #False
              EndIf 
              
              ; jumping
              If *e\jumping = #True And *e\onground = #True
                     *e\vy = -*e\jump_height
                     *e\onground = #False 
              EndIf 
              
              ; collision top
              If ((check_solid( *e\x + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + *e\vy)) And *e\vy < 0) And *e\is_ghost = #False 
                     *e\vy = 0  
              EndIf 
              
              
              ; wraping   
              If *e\wrap = #True 
                     If *e\x < -1   : *e\x = 144 - 8 : EndIf
                     If *e\x > 17*8  : *e\x = 1      : EndIf 
              Else
                     If *e\x < -1    : *e\deleteme = #True  : EndIf
                     If *e\x > 17*8  : *e\deleteme = #True  : EndIf 
              EndIf 
              
              ; lock velocity
              If *e\vx > 1.0 : *e\vx = 1.0: EndIf
              If *e\vx <-1.0 : *e\vx = -1.0 : EndIf
              
              ; update position
              *e\x = *e\x + *e\vx 
              *e\y = *e\y + *e\vy
       EndIf
       
EndProcedure

Procedure entity_collide(*a.Entity, *b.Entity)
       If (*b\x > = *a\x + 8) Or (*b\x + 8 <= *a\x) Or (*b\y > = *a\y + 8) Or  (*b\y + 8 <= *a\y)
              ProcedureReturn #False 
       Else
              ProcedureReturn #True 
       EndIf 
EndProcedure

Procedure entity_collide_point(*e.Entity, x.f, y.f, velocity.b = #False)
       
       If velocity = #False 
              If x >= *e\x  And x < *e\x + 7 And y >= *e\y  And y < *e\y + 7
                     ProcedureReturn #True 
              Else
                     ProcedureReturn #False  
              EndIf  
       Else 
              If x >= *e\x + *e\vx  And x < *e\x + 7 + *e\vx And y >= *e\y + *e\vy  And y < *e\y + 7 + *e\vy
                     ProcedureReturn #True 
              Else
                     ProcedureReturn #False  
              EndIf
       EndIf 
EndProcedure


;-Datasection
DataSection
       palette:
       Data.l 16711935,2890778,6104925,5455537,5733871,7720447,7401639,6600504,7958821,7288361,13196603,16164417,16248691,16053492,12759188,8809558,5717043
       end_palette:
       
       
       
       tilemap:  
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  3, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0 
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  2,  2,  2,  2,  2,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2 
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  0,  0,  0,  2,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  3, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  1, 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1
       
       
       end_tilemap:
       
       
       texture:
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$1,$1,$1,$1,$C,$C,$C,$C,$C,$C,$C,$C,$1,$1,$1,$1,$1,$6,$6,$D,$0,$0,$0,$0,$0,$0,$0,$0,$6,$6,$D,$1,$1,$1,$1,$1
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$3,$4,$4,$4,$5,$5,$5,$A,$C,$C,$C,$C,$C,$C,$B,$6,$6,$6,$6,$8,$7,$D,$D,$D,$D,$D,$0,$0,$0,$0,$0,$7,$D,$D,$8,$6,$6,$6,$6
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$2,$3,$3,$3,$3,$3,$4,$A,$A,$C,$C,$C,$C,$B,$B,$D,$D,$D,$D,$8,$7,$7,$D,$E,$E,$0,$0,$0,$D,$0,$0,$7,$7,$D,$8,$D,$D,$D,$D
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$2,$2,$3,$3,$3,$3,$3,$A,$A,$A,$C,$C,$B,$B,$B,$7,$7,$7,$7,$8,$7,$7,$D,$0,$0,$0,$0,$D,$D,$1,$0,$7,$7,$D,$8,$7,$7,$7,$7
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$1,$1,$1,$1,$A,$A,$A,$9,$B,$B,$B,$B,$9,$9,$9,$9,$9,$7,$7,$D,$0,$E,$0,$0,$D,$D,$D,$9,$7,$7,$D,$9,$9,$9,$9,$9
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$4,$5,$5,$5,$1,$3,$4,$4,$A,$A,$9,$9,$9,$B,$B,$B,$9,$9,$9,$9,$9,$8,$9,$7,$D,$D,$E,$9,$9,$9,$9,$A,$8,$9,$7,$9,$9,$9,$9,$9
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$3,$3,$3,$4,$1,$2,$3,$3,$A,$9,$9,$9,$9,$9,$B,$B,$A,$A,$A,$A,$9,$A,$9,$8,$E,$E,$9,$9,$9,$A,$A,$0,$A,$9,$8,$9,$A,$A,$A,$A
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$3,$3,$3,$3,$1,$2,$2,$3,$9,$9,$9,$9,$9,$9,$9,$B,$1,$1,$1,$1,$1,$A,$A,$A,$A,$A,$A,$A,$A,$0,$0,$0,$A,$A,$A,$1,$1,$1,$1,$1
       Data.b $0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $9,$9,$5,$4,$4,$2,$9,$9,$9,$9,$5,$4,$4,$2,$9,$9,$9,$9,$5,$4,$4,$2,$9,$9,$D,$D,$0,$0,$D,$D,$D,$D,$D,$D,$D,$D,$0,$0,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D
       Data.b $4,$D,$9,$5,$2,$9,$D,$5,$4,$D,$9,$5,$2,$9,$D,$5,$4,$D,$9,$5,$2,$9,$D,$5,$E,$E,$D,$0,$E,$E,$E,$E,$E,$E,$E,$E,$0,$D,$E,$E,$0,$0,$D,$0,$0,$0,$E,$E
       Data.b $4,$D,$D,$9,$9,$D,$D,$5,$4,$D,$D,$9,$9,$D,$D,$5,$4,$D,$D,$9,$9,$D,$D,$5,$0,$0,$E,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$E,$0,$0,$0,$1,$D,$D,$0,$0,$0,$0
       Data.b $4,$D,$1,$4,$4,$1,$D,$4,$4,$D,$1,$4,$4,$1,$D,$4,$4,$D,$1,$4,$4,$1,$D,$4,$0,$0,$9,$0,$0,$0,$E,$D,$D,$E,$0,$0,$0,$9,$0,$0,$9,$D,$D,$D,$0,$0,$E,$0
       Data.b $2,$4,$4,$4,$4,$4,$4,$4,$2,$4,$4,$4,$4,$4,$A,$9,$9,$A,$4,$4,$4,$4,$4,$4,$9,$9,$9,$9,$9,$9,$E,$D,$D,$E,$9,$9,$9,$9,$9,$9,$A,$9,$9,$9,$9,$E,$D,$D
       Data.b $A,$2,$E,$E,$E,$E,$2,$A,$0,$2,$E,$E,$E,$A,$9,$9,$9,$9,$A,$E,$E,$E,$2,$0,$9,$9,$A,$9,$9,$9,$9,$E,$E,$9,$9,$9,$9,$A,$9,$9,$0,$A,$A,$9,$9,$9,$E,$E
       Data.b $9,$A,$0,$E,$E,$0,$A,$9,$0,$9,$A,$E,$E,$9,$9,$0,$0,$9,$9,$E,$E,$A,$9,$0,$A,$A,$0,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$0,$A,$A,$0,$0,$0,$A,$A,$A,$A,$A
       Data.b $0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$0,$5,$D,$0,$0,$0,$0,$0,$0,$D,$D,$0,$0,$0,$0,$0,$0,$D,$D,$0,$0,$0
       Data.b $0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$5,$4,$4,$D,$0,$0,$0,$0,$0,$4,$D,$0,$0,$0,$0,$0,$0,$5,$5,$0,$0,$0
       Data.b $0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$3,$4,$4,$4,$4,$D,$0,$0,$0,$2,$4,$4,$D,$0,$0,$0,$0,$0,$4,$4,$0,$0,$0
       Data.b $0,$3,$3,$5,$B,$A,$2,$0,$0,$0,$3,$5,$B,$A,$2,$0,$0,$0,$0,$3,$5,$B,$1,$0,$0,$2,$3,$4,$4,$4,$5,$0,$0,$0,$2,$3,$4,$5,$0,$0,$0,$0,$0,$4,$4,$0,$0,$0
       Data.b $D,$0,$B,$B,$A,$A,$0,$E,$0,$D,$B,$B,$B,$A,$E,$0,$0,$0,$0,$3,$D,$B,$0,$0,$0,$0,$2,$3,$4,$5,$0,$0,$0,$0,$0,$2,$3,$0,$0,$0,$0,$0,$0,$3,$3,$0,$0,$0
       Data.b $0,$0,$2,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$2,$0,$0,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$0,$2,$3,$0,$0,$0,$0,$0,$0,$2,$2,$0,$0,$0,$0,$0,$0,$2,$2,$0,$0,$0
       Data.b $0,$D,$3,$3,$3,$0,$0,$0,$0,$D,$3,$3,$3,$0,$0,$0,$0,$D,$3,$3,$3,$0,$0,$0,$0,$3,$3,$0,$0,$3,$3,$0,$3,$3,$3,$0,$0,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$0,$0,$0,$0,$0,$0,$3,$3,$2,$2,$0,$0,$2,$2,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$4,$1,$2,$4,$2,$0,$0,$0,$4,$1,$2,$4,$2,$0,$0,$0,$4,$1,$2,$4,$2,$0,$0,$3,$2,$2,$0,$0,$2,$2,$3,$3,$0,$0,$0,$0,$0,$0,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $4,$2,$2,$4,$4,$2,$0,$0,$4,$2,$2,$4,$4,$2,$0,$0,$4,$2,$2,$4,$4,$2,$0,$0,$3,$E,$E,$4,$4,$E,$E,$3,$3,$E,$E,$4,$4,$E,$E,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$2,$D,$9,$3,$3,$9,$D,$2,$2,$D,$9,$3,$3,$9,$D,$2,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$2,$A,$B,$5,$3,$3,$0,$0,$2,$A,$B,$5,$3,$0,$0,$0,$1,$B,$5,$3,$0,$0,$0,$0,$2,$3,$3,$3,$3,$3,$0,$0,$2,$3,$3,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $E,$0,$A,$A,$B,$B,$0,$D,$0,$E,$A,$B,$B,$B,$D,$0,$0,$0,$B,$D,$3,$0,$0,$0,$0,$D,$2,$0,$2,$3,$D,$0,$0,$D,$2,$3,$3,$3,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$2,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$2,$0,$0,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$D,$0,$0,$D,$0,$D,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$D,$D,$1,$0,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$0,$D,$0,$0,$0,$0,$D,$1,$1,$1,$1,$1,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$1,$D,$1,$0,$0,$0,$0,$1,$1,$0,$0,$D,$1,$0,$0,$1,$1,$0,$0,$D,$1,$0,$0,$D,$1,$0,$D,$1,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$1,$1,$D,$1,$0,$0,$0,$0,$0,$0,$D,$D,$1,$1,$0,$0,$0,$0,$D,$D,$1,$1,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$D,$1,$1,$1,$0,$0,$0,$0,$0,$1,$1,$D,$0,$0,$0,$1,$1,$1,$D,$1,$1,$0,$0,$1,$1,$1,$1,$D,$1,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$1,$0,$0,$0,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$0,$0,$D,$1,$0
       Data.b $0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$D,$D,$D,$D,$D,$1,$0
       Data.b $0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$1,$1,$1,$1,$1,$1,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$0,$0,$1,$1,$0,$0,$0,$1,$1,$1,$1,$1,$1,$0
       Data.b $0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$3,$D,$D,$3,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$1,$1,$1,$1,$D,$1,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$3,$3,$3,$3,$0,$0,$0,$1,$3,$D,$D,$3,$1,$0
       Data.b $0,$D,$1,$0,$0,$1,$1,$0,$0,$0,$0,$0,$D,$1,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$2,$1,$4,$4,$1,$2,$0,$0,$1,$3,$3,$3,$3,$1,$0
       Data.b $0,$D,$D,$D,$D,$0,$0,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$1,$D,$D,$D,$D,$1,$0,$0,$4,$2,$2,$2,$2,$4,$0,$1,$2,$1,$4,$4,$1,$2,$1
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$0,$D,$1,$1,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$1,$1,$1,$D,$1,$0,$D,$0,$4,$1,$1,$4,$0,$D,$1,$4,$2,$2,$2,$2,$4,$1
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$3,$5,$B,$B,$5,$3,$0,$0,$1,$4,$4,$4,$4,$1,$0
       Data.b $0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$D,$1,$1,$0,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$A,$A,$A,$A,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0
       Data.b $0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$0,$0,$0,$0
       end_texture:
       
       solid_tile:
       Data.b 1,2
       end_solid_tile:
       
       
       bin_sound_jump:
       ;  IncludeBinary "jump.wav"
       bin_sound_jump_e:
       
       bin_sound_hurt:
       ;  IncludeBinary "hurt.wav"
       bin_sound_hurt_e:
       
       bin_sound_kill:
       ;  IncludeBinary "kill.wav"
       bin_sound_kill_e:
       
       bin_sound_coin:
       ;  IncludeBinary "coin.wav"
       bin_sound_coin_e:
       
       bin_sound_falling:
       ;  IncludeBinary "falling.wav"
       bin_sound_falling_e:
       
       bin_sound_respawn:
       ;  IncludeBinary "respawn.wav"
       bin_sound_respawn_e:
       
       bin_sound_rejump:
       ;  IncludeBinary "rejump.wav"
       bin_sound_rejump_e:
       
       bin_sound_missile:
       ;  IncludeBinary "missile.wav"
       bin_sound_missile_e:
       
       bin_sound_extralife:
       ;  IncludeBinary "extralife.wav"
       bin_sound_extralife_e:
       
       
EndDataSection

Re: Petit remake d'un Mario sur Atari 7800

Publié : sam. 04/avr./2020 23:26
par Ollivier
G-Rom a écrit :je pensais avoir réglé le problème de fuite de mémoire... bizarre que cela m'ai échapper , enfin , merci de le souligné , en regardant de plus près GrabSprite() serais le fautif , c'est vrai que je ne supprime pas le sprite après le flipbuffers , mais même en le faisant , ca ne change rien :/
Ben c'est ça effectivement. GrabSprite().
Au lieu de le supprimer après le FlipBuffers, je l'ai supprimé purement et simplement. Et j'ai fait une petite "surcouche" avec une procédure DisplayTransparentSprite_().

Ça a le désavantage de faire des artefacts (autour de l'écran, et entre certains sprites (solution... Bresenham par coïncidence).

Mais ça permet d'avoir deux versions pour comparer les ressources CPU. Dans cette dernière version, j'ai été contraint de mettre un Delay() après le FlipBuffers().

Voilà, à comparer entre avec et sans GrabSprite()...
Là, il n'y a plus l'air d'avoir d'accumulation mémoire... Très sobre et sympa.

Merci, pour le partage.

Re: Petit remake d'un Mario sur Atari 7800

Publié : dim. 05/avr./2020 8:42
par Ollivier
Et j'ai rajouté les dalles amovibles (coups de tête) !
(version sans GrabSprite après FlipBuffers)

Code : Tout sélectionner

;*****************************************************************************************************************************************************************************************
;
; - Mario Atari 7800 pseudo clone
;             GRom
;

#WAVE_FILE = 0 ; undef this if you dont have sound media

Macro PlaySoundEX(id,flag)
       CompilerIf #WAVE_FILE
              PlaySound(id,flag)
       CompilerEndIf
EndMacro   

RandomSeed( Random($FFFFFF) )

Structure Entity
       SpriteId.l
       X.d
       Y.d
       VX.d
       VY.d
       AnimTime.l
       AnimSpeed.l
       FlipMe.b
       anim_left_min.l
       anim_left_max.l
       anim_right_min.l
       anim_right_max.l
       jumping.b
       jump_height.d
       onground.b
       max_velx.d
       max_vely.d 
       gravity.f
       use_physic.b
       is_ghost.b
       blink.l
       wrap.b
       deleteme.b
       girouette.I
EndStructure


Structure Pnj Extends Entity
       jumper.b
       jump_time.l  
       jump_delay.l
       direction.l ; 1 right , 0 left
       entry_mode.l; 1 out ; 0 in
       collide_time.l ; prevent infinite collision
       is_cool.b
EndStructure

Structure Coin Extends Entity
       direction.l ; 1 right , 0 left
       uncollect_time.l ; prevent collect at spawn
EndStructure


Structure Player Extends Entity
       is_die.b  
       freeze_time.l
       invincible.b
       invincible_time.l
       life.l
       next_life.l
       score.l
       direction.l ; factice
EndStructure

Structure Missile Extends Entity
       IsFalling.I
       direction.l
EndStructure




Global max_mob = 1
Global mob_spawn_delay
Global speed_factor.f = 1
Global Mario.Player
Global NewList Mob.Pnj()
Global NewList Bonus.Coin()
Global NewList Missile.Missile()

Global ScoreDelta = 50
Global Dim Exc.D(29, 19)
Global ix, iy

Mario\x = 8 * 8
Mario\y = (10 * 8) 
Mario\spriteid = 12
Mario\jump_height = 3.8
Mario\animspeed = 50
Mario\anim_right_min = 12
Mario\anim_right_max = 14
Mario\anim_left_min = 18
Mario\anim_left_max = 20
Mario\gravity = 0.2
Mario\use_physic = #True 
Mario\is_die = #False 
Mario\is_ghost = #False 
Mario\invincible = #False 
Mario\Life = 4
Mario\wrap = #True 
Mario\next_life = 3000

Declare.l getcolor(rgb)
Declare draw_value(value.l,x,y)
Declare check_solid(x.d,y.d)
Declare is_solid(tilex,tiley)
Declare spawn_mob()
Declare draw_entity(*e.entity)
Declare update_physic(*e.Entity)
Declare entity_collide(*a.Entity, *b.Entity)
Declare entity_collide_point(*e.entity,x.f,y.f, velocity.b = #False)
Declare spawn_coin(x,y,d)
Declare spawn_missile(y)
Declare draw_missile(*m.Missile)
Declare update_missile(*m.missile)




InitSprite() : InitKeyboard() : InitMouse() : InitSound() : joypad = InitJoystick()
ExamineDesktops()
Global dw = DesktopWidth(0)
Global dh = DesktopHeight(0)
Global deltatime.d = 0

OpenScreen(dw,dh,32,"",#PB_Screen_NoSynchronization)
Global gpu_texture = CreateSprite(#PB_Any,48,48,#PB_Sprite_AlphaBlending)

Global Dim Color.l(16)
CopyMemory(?palette, @Color(), ?end_palette - ?palette) 

Global Dim Texture.b(48*48)
CopyMemory(?texture, @Texture(), ?end_texture - ?texture) 

Global Dim Tilemap.b(19*16)
CopyMemory(?tilemap, @Tilemap(), ?end_tilemap - ?tilemap) 

Global Dim SolidTile.b(?end_solid_tile - ?solid_tile)
CopyMemory(?solid_tile, @SolidTile(), ?end_solid_tile - ?solid_tile) 

Global Dim SubSprite.l(36)

StartDrawing(SpriteOutput(gpu_texture))
For y = 0 To 47
       For x = 0 To 47
              index = x + 48 * y
              Plot(x,y, Color( Texture(index) ) )
       Next
Next
StopDrawing()

Procedure DisplayTransparentSprite_(N, X, Y)
       DisplayTransparentSprite(N, ((DW - DH) / 2) + (X * DH) / 128.0, Y * DH / 128)
EndProcedure


DisplaySprite(gpu_texture,0,0)
For clip = 0 To 35
       x = clip % 6
       y = clip / 6
       SubSprite(clip) = GrabSprite(#PB_Any,x*8,y*8,8,8) 
       TransparentSpriteColor(SubSprite(clip), RGB(255,0,255))
       etir = (Bool(clip = 3 Or clip = 5) + 1)
       ZoomSprite(SubSprite(clip), dh / 16, dh / 16 * etir) ; <<<<<<<<<<<<<<<<<<<<
Next


CompilerIf #WAVE_FILE
       ;   sound_jump    = LoadSound(#PB_Any,"jump.wav")
       ;   sound_hurt    = LoadSound(#PB_Any,"hurt.wav")
       ;   sound_kill    = LoadSound(#PB_Any,"kill.wav")
       ;   sound_coin    = LoadSound(#PB_Any,"coin.wav")
       ;   sound_fall    = LoadSound(#PB_Any,"falling.wav")
       ;   sound_respawn = LoadSound(#PB_Any,"respawn.wav")
       ;   sound_rejump  = LoadSound(#PB_Any,"rejump.wav")
       ;   sound_missile  = LoadSound(#PB_Any,"missile.wav")
       ;   sound_extralife  = LoadSound(#PB_Any,"extralife.wav")
       
       
       sound_jump    = CatchSound(#PB_Any,?bin_sound_jump, ?bin_sound_jump_e - ?bin_sound_jump)
       sound_hurt    = CatchSound(#PB_Any,?bin_sound_hurt, ?bin_sound_hurt_e - ?bin_sound_hurt)
       sound_kill    = CatchSound(#PB_Any,?bin_sound_kill, ?bin_sound_kill_e - ?bin_sound_kill)
       sound_coin    = CatchSound(#PB_Any,?bin_sound_coin, ?bin_sound_coin_e - ?bin_sound_coin)
       sound_fall    = CatchSound(#PB_Any,?bin_sound_falling, ?bin_sound_falling_e - ?bin_sound_falling)
       sound_respawn = CatchSound(#PB_Any,?bin_sound_respawn, ?bin_sound_respawn_e - ?bin_sound_respawn)
       sound_rejump  = CatchSound(#PB_Any,?bin_sound_rejump, ?bin_sound_rejump_e - ?bin_sound_rejump)
       sound_missile  = CatchSound(#PB_Any,?bin_sound_missile, ?bin_sound_missile_e - ?bin_sound_missile)
       sound_extralife = CatchSound(#PB_Any,?bin_sound_extralife, ?bin_sound_extralife_e - ?bin_sound_extralife)
       
       
       
       
       
       
       
       
CompilerEndIf 


; spawn_missile(14)
missile_timer = ElapsedMilliseconds() + 4000
missile_middle_timer = ElapsedMilliseconds() + 10000

; boucle principale
;
accumulator.d = 0
While #True
       ExamineKeyboard()
       
       deltatime = (ElapsedMilliseconds() - lasttime.d) / 1000
       lasttime = ElapsedMilliseconds()
       accumulator + deltatime
       
       If mob_spawn_delay < ElapsedMilliseconds() And ListSize(Mob()) < max_mob
              mob_spawn_delay = ElapsedMilliseconds() + Random(3000,750)
              spawn_mob()
       EndIf
       
       
       ;
       ;-INPUT
       ;
       If KeyboardPushed(#PB_Key_Escape)
              Break
       EndIf
       
       
       If Mario\is_die = #False 
              
              If joypad
                     If ExamineJoystick(0)
                            joy_axisx = JoystickAxisX(0) 
                            joy_button = JoystickButton(0,3)
                     EndIf
              EndIf 
              
              If KeyboardPushed(#PB_Key_Right) Or joy_axisx = 1
                     Mario\vx = 1
                     Mario\flipme = #False 
              EndIf
              
              If KeyboardPushed(#PB_Key_Left) Or joy_axisx = -1
                     Mario\vx = -1
                     Mario\flipme = #True 
              EndIf
              
              If KeyboardPushed(#PB_Key_LeftControl) Or joy_button = 1
                     Mario\jumping = #True 
                     
                     If sound_jump_flag = 0
                            sound_jump_flag = 1
                            PlaySoundEX(sound_jump,#PB_Sound_MultiChannel)
                     EndIf 
                     
              Else
                     sound_jump_flag = 0
                     Mario\jumping = #False      
              EndIf
              
              If Not (KeyboardPushed(#PB_Key_Right) Or joy_axisx = 1) And Not (KeyboardPushed(#PB_Key_Left)  Or joy_axisx = -1 )
                     Mario\vx = 0    
              EndIf
              
       EndIf 
       
       
       ;-GAME LOGIC
       
       ; Spawn missile
       
       If Mario\y < 32 And missile_timer < ElapsedMilliseconds()
              missile_timer = ElapsedMilliseconds() + 5000
              spawn_missile(Random(2))
              PlaySoundEX(sound_missile,#PB_Sound_MultiChannel)
       ElseIf Mario\y > 32
              missile_timer = ElapsedMilliseconds() + 5000
       EndIf   
       
       If Mario\y > 32 And Mario\y< 96 And missile_middle_timer < ElapsedMilliseconds()
              missile_middle_timer = ElapsedMilliseconds() + 10000
              spawn_missile(Random(10,4))
              PlaySoundEX(sound_missile,#PB_Sound_MultiChannel)
       ElseIf (Mario\y < 32 Or Mario\y > 96)
              missile_middle_timer = ElapsedMilliseconds() + 10000
       EndIf   
       
       
       
       If Mario\score => Mario\next_life 
              Mario\next_life + 3000
              Mario\life + 1
              PlaySoundEX(sound_extralife,#PB_Sound_MultiChannel)
       EndIf 
       
       ; Mario die ( jumping )
       If Mario\is_die And Mario\freeze_time < ElapsedMilliseconds() And Mario\use_physic = #False 
              Mario\use_physic = #True   
              Mario\vy = -Mario\jump_height
              PlaySoundEX(sound_fall,#PB_Sound_MultiChannel)
       EndIf
       
       If Mario\is_die And Mario\y > 2048
              Mario\Life - 1
              If Mario\Life = 0
                     End
              EndIf
              
              Mario\invincible = #True 
              Mario\invincible_time = ElapsedMilliseconds() + 2000
              Mario\x = 8 * 8
              Mario\y = (10 * 8) 
              Mario\vy = 0
              Mario\vx = 0
              Mario\is_ghost = #False 
              Mario\is_die = #False 
              PlaySoundEX(sound_respawn,#PB_Sound_MultiChannel)
       EndIf
       
       
       If Mario\invincible And Mario\invincible_time > ElapsedMilliseconds()
              Mario\blink+1 : Mario\blink%4
       ElseIf Mario\invincible And Mario\invincible_time < ElapsedMilliseconds()
              Mario\invincible = #False 
              Mario\blink = 0
       EndIf 
       
       ForEach(Bonus())
              
              If( entity_collide_point(@Mario,Bonus()\x + 4 , Bonus()\y + 4) ) And Bonus()\uncollect_time < ElapsedMilliseconds()
                     Mario\score + 1000
                     
                     PlaySoundEX(sound_coin,#PB_Sound_MultiChannel)
                     
                     If DeleteElement(Bonus(),1)=0
                            Break
                     EndIf 
                     
              EndIf
              
              If Bonus()\direction = 1
                     Bonus()\vx = 0.5
              Else
                     Bonus()\vx = -0.5
              EndIf
              
              If Bonus()\deleteme
                     DeleteElement(Bonus())
              EndIf    
       Next
       
       
       ForEach(@Mob())
              
              Mob()\vx = 0.2
              
              If Mob()\jumper = #True 
                     If Mob()\jump_time < ElapsedMilliseconds()
                            Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                            Mob()\jumping = #True 
                     Else
                            Mob()\jumping = #False
                     EndIf
              EndIf 
              
              If Mob()\girouette
                     Mob()\girouette = 0
                     Mob()\Direction ! 1
              EndIf
              
              If Mob()\direction = 1
                     Mob()\vx = 0.25
              Else
                     Mob()\vx = -0.25
              EndIf 
              
              
              ; down pipe enter
              ;
              If Round(Mob()\x/8,#PB_Round_Down) = 0 And Round(Mob()\y/8,#PB_Round_Down) = 14 And Mob()\vx < 0
                     Mob()\use_physic = #False 
                     Mob()\entry_mode = 0
                     Mob()\is_cool = #True 
              EndIf
              
              If Round(Mob()\x/8,#PB_Round_Down) = 16 And Round(Mob()\y/8,#PB_Round_Down) = 14 And Mob()\vx > 0
                     Mob()\use_physic = #False 
                     Mob()\entry_mode = 0
                     Mob()\is_cool = #True
              EndIf
              
              
              If Mob()\use_physic = #False 
                     
                     ; down pipe enter move
                     If Mob()\entry_mode = 0
                            If Round(Mob()\y/8,#PB_Round_Down) > 12
                                   Mob()\y - 0.25
                            EndIf 
                            
                            ; left pipe
                            If Mob()\vx < 0 And Round(Mob()\y/8,#PB_Round_Down) = 12
                                   Mob()\x - 0.25
                                   If Round(Mob()\x/8,#PB_Round_Down) = 0
                                          Mob()\x  = 1*8
                                          Mob()\y  = 1*8
                                          Mob()\entry_mode = 1
                                          Mob()\direction = 1
                                          Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                                   EndIf             
                            EndIf 
                            
                            ; right pipe
                            If Mob()\vx > 0 And Round(Mob()\y/8,#PB_Round_Down) = 12
                                   Mob()\x + 0.25
                                   If Round(Mob()\x/8,#PB_Round_Down) = 17
                                          Mob()\x  = 16*8
                                          Mob()\y  = 1*8
                                          Mob()\entry_mode = 1
                                          Mob()\direction = 0
                                          Mob()\jump_time = ElapsedMilliseconds() + Mob()\jump_delay
                                   EndIf 
                            EndIf 
                     EndIf 
                     
                     ; up pipe exit
                     If Mob()\entry_mode = 1
                            If Mob()\vx > 0
                                   Mob()\x + 0.25  
                                   If Round(Mob()\x/8,#PB_Round_Down) = 1 : Mob()\use_physic = #True : Mob()\is_cool = #False : EndIf
                            EndIf
                            
                            If Mob()\vx < 0
                                   Mob()\x - 0.25 
                                   If Round(Mob()\x/8,#PB_Round_Down) = 15 : Mob()\use_physic = #True : Mob()\is_cool = #False : EndIf
                            EndIf
                            
                     EndIf
              EndIf
              
       Next
       
       
       
       While ( accumulator > 1.0/60.0 )
              ;-PHYSIC
              ;
              
              update_physic(@Mario)
              
              ForEach (Bonus())
                     update_physic(@Bonus())  
              Next
              
              ; collide Mob/Mob , Mob/Mario
              ForEach(Mob())
                     
                     ; mob / mob 
                     *c.Pnj = @Mob()
                     PushListPosition(Mob())
                     ForEach Mob()
                            
                            If @Mob() <> *c And Mob()\collide_time < ElapsedMilliseconds()
                                   If entity_collide(*c,@Mob())
                                          *c\direction + 1 : *c\direction % 2
                                          Mob()\direction + 1 : Mob()\direction %2
                                          Mob()\collide_time = ElapsedMilliseconds() + 250            
                                   EndIf 
                            EndIf 
                            
                     Next
                     PopListPosition(Mob())
                     
                     If Mob()\is_cool = #False 
                            ; mob / mario      
                            If entity_collide(@Mario,@Mob()) And Mario\is_die = #False 
                                   
                                   
                                   If Mario\y < Mob()\y 
                                          
                                          Mario\vy = -(Mario\jump_height/1.1)
                                          
                                          If Random(10) = 0
                                                 spawn_coin(Mob()\x,Mob()\y,(Mob()\direction+1)%2 )
                                          EndIf 
                                          
                                          Mario\score + ScoreDelta
                                          ScoreDelta * 2
                                          
                                          max_mob + 1
                                          If max_mob > 8
                                                 max_mob = 8
                                          EndIf 
                                          
                                          PlaySoundEX(sound_kill,#PB_Sound_MultiChannel)
                                          PlaySoundEX(sound_rejump,#PB_Sound_MultiChannel)
                                          
                                          If DeleteElement(Mob(),1) = 0
                                                 Break   
                                          EndIf 
                                          
                                   ElseIf Mario\y  >= Mob()\y And Mario\invincible = #False 
                                          Mario\vx = 0
                                          Mario\vy = 0
                                          Mario\is_die = #True 
                                          Mario\is_ghost = #True
                                          Mario\freeze_time = ElapsedMilliseconds() + 500
                                          Mario\use_physic = #False
                                          Mario\spriteid = 34
                                          
                                          PlaySoundEX(sound_hurt,#PB_Sound_MultiChannel)
                                          
                                          If Mario\life = 0
                                                 
                                                 spr = GrabSprite(#PB_Any,0,0,dw,dh)
                                                 UsePNGImageEncoder()
                                                 SaveSprite(spr,"MyScore.png",#PB_ImagePlugin_PNG)
                                                 
                                                 End
                                          EndIf
                                          
                                   EndIf 
                            EndIf 
                     EndIf 
                     update_physic(@Mob())
                     
                     
              Next
              
                     
             
              ; missile "physic..."
              ;
              ForEach Missile()
                     update_missile(@Missile())
                     
                            ; mISSILE / mario      
                            If entity_collide(@Mario, @Missile() ) And Mario\is_die = #False 
                                   
                                   
                                   If Mario\y < Missile()\y 
                                          
                                          Missile()\IsFalling = 1
                                          
                                          Mario\vy = -(Mario\jump_height/1.1)
                                          
                                          If Random(10) = 0
                                                 spawn_coin(Missile()\x,Missile()\y,(Missile()\direction+1)%2 )
                                          EndIf 
                                          
                                          ScoreDelta * 2
                                          Mario\score + ScoreDelta
                                          ScoreDelta * 2
                                          
                                   ElseIf Mario\y  >= Missile()\y And Mario\invincible = #False 
                                          Mario\vx = 0
                                          Mario\vy = 0
                                          Mario\is_die = #True 
                                          Mario\is_ghost = #True
                                          Mario\freeze_time = ElapsedMilliseconds() + 500
                                          Mario\use_physic = #False
                                          Mario\spriteid = 34
                                          Mario\life - 1
                                          
                                          PlaySoundEX(sound_hurt,#PB_Sound_MultiChannel)
                                          
                                          If Mario\life = 0
                                                 
                                                 spr = GrabSprite(#PB_Any,0,0,dw,dh)
                                                 UsePNGImageEncoder()
                                                 SaveSprite(spr,"MyScore.png",#PB_ImagePlugin_PNG)
                                                 
                                                 End
                                          EndIf
                                          
                                   EndIf 
                            EndIf 
                     
                     
                     
                     If(Missile()\x < -200 Or Missile()\x > 328) Or Missile()\y > 2048
                            DeleteElement(Missile())
                     EndIf
                     
                     
                     
                     
              Next 
              
              accumulator - (1.0/60.0)
       Wend 
       
       
       ;
       ;-DRAWING
       ;
       
       ClearScreen(RGB(26,28,44))
       
       ; draw mob
       ForEach(Mob())
              draw_entity(@Mob())  
       Next
       
       ForEach (Bonus())
              draw_entity(@Bonus())  
       Next
       
       
       ForEach Missile()
              draw_missile(@Missile())
       Next 
       
       ; draw tilemap
       For y = 0 To 15
              For x = 0 To 17
                     index = x + 19 * y
                     DisplayTransparentSprite_( SubSprite(Tilemap( index )) ,x*8,y*8 + Exc(x, y) )
                     If Exc(x, y) < 0
                            Exc(x, y) + 0.25
                     EndIf
                     
                     ;       
              Next
       Next
       
       ; draw mario
       draw_entity(@Mario)
       
       ; draw life
       For i = 0 To Mario\Life - 2
              DisplayTransparentSprite_(SubSprite(35),8+(i*8),0)
       Next
       ; draw score   
       draw_value( Mario\score, (64 - (((Len(Str(Mario\score))-1)*8)/2))+8 ,4)
       
       ;DisplayTransparentSprite_(SubSprite(coin_id+2),(8+128)-8*4,0)
       FlipBuffers()
       Delay(16)
Wend

CloseScreen()
End 



Procedure.l getcolor(rgb)
       For i = 0 To 15
              If Color(i) = rgb
                     ProcedureReturn i
              EndIf
       Next 
EndProcedure



Procedure draw_value(value.l,x,y)
       str$ = Str(value)  
       For i = 0 To Len(str$)-1
              n.l = Val(Mid(str$,i+1,1))
              DisplayTransparentSprite_( SubSprite( 24 + n ) , x + (i * 6),y)
       Next
EndProcedure


Procedure check_solid(x.d, y.d)
       ProcedureReturn is_solid(Round(x/8,#PB_Round_Down),Round(y/8,#PB_Round_Down))
EndProcedure


Procedure is_solid(tilex,tiley)
       index = tilex + 19 * tiley
       If index >= 0 And index < (19*16)
              tile_id = Tilemap(index)
              For i = 0 To (?end_solid_tile - ?solid_tile) - 1
                     If tile_id = SolidTile(i)
                            ProcedureReturn #True
                     EndIf 
              Next
       EndIf 
       ProcedureReturn #False 
EndProcedure


Procedure spawn_mob()
       AddElement(Mob())
       
       
       Mob()\jump_height    = 1.0
       
       If Random(9) > 2 
              Mob()\anim_left_min  = 21
              Mob()\anim_left_max  = 22
              Mob()\anim_right_min = 21
              Mob()\anim_right_max = 22
              Mob()\animspeed      = 25
              Mob()\jumper         = #True 
              Mob()\jump_delay     = 250
       Else 
              Mob()\anim_left_min  = 6
              Mob()\anim_left_max  = 8
              Mob()\anim_right_min = 6
              Mob()\anim_right_max = 8
              Mob()\animspeed      = 100
              Mob()\jumper         = #False
       EndIf 
       
       
       Mob()\gravity        = 0.1  
       Mob()\direction = Random(1)
       Mob()\use_physic = #False
       Mob()\entry_mode = 1
       Mob()\is_ghost = #False 
       Mob()\is_cool = #False 
       Mob()\wrap = #True 
       
       If Mob()\direction = 1
              Mob()\x  = 0
              Mob()\y  = 1*8
       Else
              Mob()\x  = 16*8 
              Mob()\y  = 1*8
       EndIf
       
       
EndProcedure


Procedure spawn_coin(x,y,direction)
       AddElement(Bonus())
       
       Bonus()\jumping = #True 
       Bonus()\jump_height    = 0.5
       
       Bonus()\anim_left_min  = 15
       Bonus()\anim_left_max  = 17
       Bonus()\anim_right_min = 15
       Bonus()\anim_right_max = 17
       Bonus()\animspeed      = 25
       
       Bonus()\gravity        = 0.05
       Bonus()\use_physic = #True
       Bonus()\is_ghost = #False 
       Bonus()\wrap = #True
       Bonus()\x  = x
       Bonus()\y  = y
       Bonus()\direction = direction
       Bonus()\uncollect_time = ElapsedMilliseconds() + 100
       If Bonus()\direction = 1
              Bonus()\vx = 0.5
              Bonus()\vy = -1.0
       Else
              Bonus()\vx = -0.5
              Bonus()\vy = -1.0
       EndIf
       
EndProcedure


Procedure spawn_missile(y)
       AddElement(Missile())
       
       Missile()\use_physic = #False 
       Missile()\direction = Random(1)
       
       If  Missile()\direction
              Missile()\x = - 16
              Missile()\y = y * 8
              Missile()\vx = 1
       Else
              Missile()\x = 128 
              Missile()\y = y * 8
              Missile()\vx = -1
       EndIf
       
       
       
       
EndProcedure

Procedure draw_missile(*m.Missile)
       
       If  Missile()\direction
              DisplayTransparentSprite_( SubSprite(9) , *m\x, *m\y) ; tail
              DisplayTransparentSprite_( SubSprite(4) , *m\x + 8, *m\y) ; head
       Else
              DisplayTransparentSprite_( SubSprite(10) , *m\x+8, *m\y) ; tail
              DisplayTransparentSprite_( SubSprite(11) , *m\x, *m\y)   ; head    
       EndIf
       
       
       
       
EndProcedure

Procedure update_missile(*m.missile)
       If *m\IsFalling
              *m\vx = 0
              *m\vy + 0.2
       EndIf       
       *m\x + *m\vx  
       *m\y + *m\vy
EndProcedure

Procedure draw_entity(*e.entity)
       
       If *e\vx <> 0 And *e\is_ghost = #False 
              
              If ( *e\animtime < ElapsedMilliseconds() )
                     *e\animtime = ElapsedMilliseconds() + *e\animspeed
                     *e\spriteid+1
                     
                     If *e\flipme = #False   
                            If *e\spriteid < *e\anim_right_min : *e\spriteid = *e\anim_right_min : EndIf
                            If *e\spriteid > *e\anim_right_max
                                   *e\spriteid = *e\anim_right_min
                            EndIf       
                     Else 
                            If *e\spriteid < *e\anim_left_max : *e\spriteid = *e\anim_left_max : EndIf
                            If *e\spriteid > *e\anim_left_max
                                   *e\spriteid = *e\anim_left_min
                            EndIf
                     EndIf 
                     
              EndIf
              
       ElseIf *e\vx = 0 And *e\is_ghost = #False 
              If *e\flipme = #False 
                     *e\spriteid = *e\anim_right_min
              Else
                     *e\spriteid = *e\anim_left_min
              EndIf 
       EndIf
       
       If *e\blink = 1 
              DisplayTransparentSprite_( SubSprite(0) , *e\x, *e\y)
       Else
              DisplayTransparentSprite_( SubSprite(*e\spriteid) , *e\x, *e\y)
       EndIf
       
EndProcedure



Procedure update_physic(*e.Entity)
       
       If *e\use_physic
              
              
              ; side collision
              If check_solid( *e\x + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + 7 + *e\vy) Or check_solid( *e\x + *e\vx, *e\y + 7 + *e\vy)
                     *e\vx = 0
              EndIf 
              
              ; collision down
              If (check_solid( *e\x , *e\y + 8 + *e\vy) Or check_solid( *e\x + 7 , *e\y + 8 + *e\vy)) And *e\is_ghost = #False 
                     *e\vy = 0
                     *e\onground = #True
                     If *e = @Mario
                            ScoreDelta = 50
                     EndIf

              Else
                     *e\vy = *e\vy + *e\gravity ; falling
                     *e\onground = #False
              EndIf 
              
              ; jumping
              If *e\jumping = #True And *e\onground = #True
                     *e\vy = -*e\jump_height
                     *e\onground = #False 
              EndIf 
              
              ; collision top
              If *e\is_ghost = #False
                     If *e\vy < 0
                            If check_solid(*e\x + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + *e\vy)
                                   ix = Round((*e\x + *e\vx) / 8, #PB_Round_Down)
                                   iy = Round((*e\y + *e\vy) / 8, #PB_Round_Down)
                                   If Mod(*e\x, 8) <= 6
                                          Exc(ix, iy) = - 2
                                   EndIf
                                   If Mod(*e\x, 8) > 2
                                          Exc(ix + 1, iy) = - 2
                                   EndIf
                            EndIf 
                            If check_solid(*e\x + *e\vx, *e\y + *e\vy) Or check_solid( *e\x + 7 + *e\vx, *e\y + *e\vy)
                                   *e\vy = 0  
                            EndIf
                     EndIf
              EndIf
              
              ; floor hit
              If (check_solid( *e\x , *e\y + 8 + *e\vy) Or check_solid( *e\x + 7 , *e\y + 8 + *e\vy)) And *e\is_ghost = #False 
                     
                     ix = Round((*e\x + *e\vx) / 8, #PB_Round_Down)
                     iy = Round((*e\y + *e\vy) / 8, #PB_Round_Down)
                     ;If Mod(*e\x, 8) <= 6
                            If Exc(ix, iy + 1) = - 2
                                   ;*e\jumping = #True
                                   *e\vy = -1.5
                                   ;*e\vx = 0.0 - *e\vx
                                   *e\girouette = 1
                            EndIf
                     ;EndIf
                     ;If Mod(*e\x, 8) > 2
                     ;       If Exc(ix + 1, iy + 1) = - 2
                     ;              ;*e\jumping = #True
                     ;              *e\vy = -1.5
                     ;              *e\vx = 0.0 - *e\vx
                     ;       EndIf
                     ;EndIf
              EndIf
              
              ; screen wraping   
              If *e\wrap = #True 
                     If *e\x < -1   : *e\x = 144 - 8 : EndIf
                     If *e\x > 17*8  : *e\x = 1      : EndIf 
              Else
                     If *e\x < -1    : *e\deleteme = #True  : EndIf
                     If *e\x > 17*8  : *e\deleteme = #True  : EndIf 
              EndIf 
              
              ; lock velocity
              If *e\vx > 1.0 : *e\vx = 1.0: EndIf
              If *e\vx <-1.0 : *e\vx = -1.0 : EndIf
              
              ; update position
              *e\x = *e\x + *e\vx 
              *e\y = *e\y + *e\vy
       EndIf
       
EndProcedure

Procedure entity_collide(*a.Entity, *b.Entity)
       If (*b\x > = *a\x + 8) Or (*b\x + 8 <= *a\x) Or (*b\y > = *a\y + 8) Or  (*b\y + 8 <= *a\y)
              ProcedureReturn #False 
       Else
              ProcedureReturn #True 
       EndIf 
EndProcedure

Procedure entity_collide_point(*e.Entity, x.f, y.f, velocity.b = #False)
       
       If velocity = #False 
              If x >= *e\x  And x < *e\x + 7 And y >= *e\y  And y < *e\y + 7
                     ProcedureReturn #True 
              Else
                     ProcedureReturn #False  
              EndIf  
       Else 
              If x >= *e\x + *e\vx  And x < *e\x + 7 + *e\vx And y >= *e\y + *e\vy  And y < *e\y + 7 + *e\vy
                     ProcedureReturn #True 
              Else
                     ProcedureReturn #False  
              EndIf
       EndIf 
EndProcedure


;-Datasection
DataSection
       palette:
       Data.l 16711935,2890778,6104925,5455537,5733871,7720447,7401639,6600504,7958821,7288361,13196603,16164417,16248691,16053492,12759188,8809558,5717043
       end_palette:
       
       
       
       tilemap:  
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  3, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0 
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  2,  2,  2,  2,  2,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2 
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  0,  0,  0,  2,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  2, 2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  3, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0
       Data.b  0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       Data.b  1, 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1
       
       
       end_tilemap:
       
       
       texture:
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$1,$1,$1,$1,$C,$C,$C,$C,$C,$C,$C,$C,$1,$1,$1,$1,$1,$6,$6,$D,$0,$0,$0,$0,$0,$0,$0,$0,$6,$6,$D,$1,$1,$1,$1,$1
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$3,$4,$4,$4,$5,$5,$5,$A,$C,$C,$C,$C,$C,$C,$B,$6,$6,$6,$6,$8,$7,$D,$D,$D,$D,$D,$0,$0,$0,$0,$0,$7,$D,$D,$8,$6,$6,$6,$6
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$2,$3,$3,$3,$3,$3,$4,$A,$A,$C,$C,$C,$C,$B,$B,$D,$D,$D,$D,$8,$7,$7,$D,$E,$E,$0,$0,$0,$D,$0,$0,$7,$7,$D,$8,$D,$D,$D,$D
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$2,$2,$3,$3,$3,$3,$3,$A,$A,$A,$C,$C,$B,$B,$B,$7,$7,$7,$7,$8,$7,$7,$D,$0,$0,$0,$0,$D,$D,$1,$0,$7,$7,$D,$8,$7,$7,$7,$7
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$1,$1,$1,$1,$A,$A,$A,$9,$B,$B,$B,$B,$9,$9,$9,$9,$9,$7,$7,$D,$0,$E,$0,$0,$D,$D,$D,$9,$7,$7,$D,$9,$9,$9,$9,$9
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$4,$5,$5,$5,$1,$3,$4,$4,$A,$A,$9,$9,$9,$B,$B,$B,$9,$9,$9,$9,$9,$8,$9,$7,$D,$D,$E,$9,$9,$9,$9,$A,$8,$9,$7,$9,$9,$9,$9,$9
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$3,$3,$3,$4,$1,$2,$3,$3,$A,$9,$9,$9,$9,$9,$B,$B,$A,$A,$A,$A,$9,$A,$9,$8,$E,$E,$9,$9,$9,$A,$A,$0,$A,$9,$8,$9,$A,$A,$A,$A
       Data.b $0,$0,$0,$0,$0,$0,$0,$0,$3,$3,$3,$3,$1,$2,$2,$3,$9,$9,$9,$9,$9,$9,$9,$B,$1,$1,$1,$1,$1,$A,$A,$A,$A,$A,$A,$A,$A,$0,$0,$0,$A,$A,$A,$1,$1,$1,$1,$1
       Data.b $0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$4,$5,$D,$5,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $9,$9,$5,$4,$4,$2,$9,$9,$9,$9,$5,$4,$4,$2,$9,$9,$9,$9,$5,$4,$4,$2,$9,$9,$D,$D,$0,$0,$D,$D,$D,$D,$D,$D,$D,$D,$0,$0,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D
       Data.b $4,$D,$9,$5,$2,$9,$D,$5,$4,$D,$9,$5,$2,$9,$D,$5,$4,$D,$9,$5,$2,$9,$D,$5,$E,$E,$D,$0,$E,$E,$E,$E,$E,$E,$E,$E,$0,$D,$E,$E,$0,$0,$D,$0,$0,$0,$E,$E
       Data.b $4,$D,$D,$9,$9,$D,$D,$5,$4,$D,$D,$9,$9,$D,$D,$5,$4,$D,$D,$9,$9,$D,$D,$5,$0,$0,$E,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$E,$0,$0,$0,$1,$D,$D,$0,$0,$0,$0
       Data.b $4,$D,$1,$4,$4,$1,$D,$4,$4,$D,$1,$4,$4,$1,$D,$4,$4,$D,$1,$4,$4,$1,$D,$4,$0,$0,$9,$0,$0,$0,$E,$D,$D,$E,$0,$0,$0,$9,$0,$0,$9,$D,$D,$D,$0,$0,$E,$0
       Data.b $2,$4,$4,$4,$4,$4,$4,$4,$2,$4,$4,$4,$4,$4,$A,$9,$9,$A,$4,$4,$4,$4,$4,$4,$9,$9,$9,$9,$9,$9,$E,$D,$D,$E,$9,$9,$9,$9,$9,$9,$A,$9,$9,$9,$9,$E,$D,$D
       Data.b $A,$2,$E,$E,$E,$E,$2,$A,$0,$2,$E,$E,$E,$A,$9,$9,$9,$9,$A,$E,$E,$E,$2,$0,$9,$9,$A,$9,$9,$9,$9,$E,$E,$9,$9,$9,$9,$A,$9,$9,$0,$A,$A,$9,$9,$9,$E,$E
       Data.b $9,$A,$0,$E,$E,$0,$A,$9,$0,$9,$A,$E,$E,$9,$9,$0,$0,$9,$9,$E,$E,$A,$9,$0,$A,$A,$0,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$0,$A,$A,$0,$0,$0,$A,$A,$A,$A,$A
       Data.b $0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$3,$3,$3,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$2,$4,$2,$1,$4,$0,$0,$0,$0,$5,$D,$0,$0,$0,$0,$0,$0,$D,$D,$0,$0,$0,$0,$0,$0,$D,$D,$0,$0,$0
       Data.b $0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$2,$4,$4,$2,$2,$4,$0,$0,$5,$4,$4,$D,$0,$0,$0,$0,$0,$4,$D,$0,$0,$0,$0,$0,$0,$5,$5,$0,$0,$0
       Data.b $0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$3,$4,$4,$4,$4,$D,$0,$0,$0,$2,$4,$4,$D,$0,$0,$0,$0,$0,$4,$4,$0,$0,$0
       Data.b $0,$3,$3,$5,$B,$A,$2,$0,$0,$0,$3,$5,$B,$A,$2,$0,$0,$0,$0,$3,$5,$B,$1,$0,$0,$2,$3,$4,$4,$4,$5,$0,$0,$0,$2,$3,$4,$5,$0,$0,$0,$0,$0,$4,$4,$0,$0,$0
       Data.b $D,$0,$B,$B,$A,$A,$0,$E,$0,$D,$B,$B,$B,$A,$E,$0,$0,$0,$0,$3,$D,$B,$0,$0,$0,$0,$2,$3,$4,$5,$0,$0,$0,$0,$0,$2,$3,$0,$0,$0,$0,$0,$0,$3,$3,$0,$0,$0
       Data.b $0,$0,$2,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$2,$0,$0,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$0,$2,$3,$0,$0,$0,$0,$0,$0,$2,$2,$0,$0,$0,$0,$0,$0,$2,$2,$0,$0,$0
       Data.b $0,$D,$3,$3,$3,$0,$0,$0,$0,$D,$3,$3,$3,$0,$0,$0,$0,$D,$3,$3,$3,$0,$0,$0,$0,$3,$3,$0,$0,$3,$3,$0,$3,$3,$3,$0,$0,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$3,$3,$3,$3,$0,$0,$0,$3,$0,$0,$0,$0,$0,$0,$3,$3,$2,$2,$0,$0,$2,$2,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$4,$1,$2,$4,$2,$0,$0,$0,$4,$1,$2,$4,$2,$0,$0,$0,$4,$1,$2,$4,$2,$0,$0,$3,$2,$2,$0,$0,$2,$2,$3,$3,$0,$0,$0,$0,$0,$0,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $4,$2,$2,$4,$4,$2,$0,$0,$4,$2,$2,$4,$4,$2,$0,$0,$4,$2,$2,$4,$4,$2,$0,$0,$3,$E,$E,$4,$4,$E,$E,$3,$3,$E,$E,$4,$4,$E,$E,$3,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$0,$4,$4,$4,$0,$0,$0,$0,$2,$D,$9,$3,$3,$9,$D,$2,$2,$D,$9,$3,$3,$9,$D,$2,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$2,$A,$B,$5,$3,$3,$0,$0,$2,$A,$B,$5,$3,$0,$0,$0,$1,$B,$5,$3,$0,$0,$0,$0,$2,$3,$3,$3,$3,$3,$0,$0,$2,$3,$3,$3,$3,$3,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $E,$0,$A,$A,$B,$B,$0,$D,$0,$E,$A,$B,$B,$B,$D,$0,$0,$0,$B,$D,$3,$0,$0,$0,$0,$D,$2,$0,$2,$3,$D,$0,$0,$D,$2,$3,$3,$3,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$2,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$2,$0,$0,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$D,$0,$0,$D,$0,$D,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0
       Data.b $0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$0,$0,$0,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$D,$D,$1,$0,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$0,$D,$0,$0,$0,$0,$D,$1,$1,$1,$1,$1,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$1,$D,$1,$0,$0,$0,$0,$1,$1,$0,$0,$D,$1,$0,$0,$1,$1,$0,$0,$D,$1,$0,$0,$D,$1,$0,$D,$1,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$1,$1,$D,$1,$0,$0,$0,$0,$0,$0,$D,$D,$1,$1,$0,$0,$0,$0,$D,$D,$1,$1,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$D,$1,$1,$1,$0,$0,$0,$0,$0,$1,$1,$D,$0,$0,$0,$1,$1,$1,$D,$1,$1,$0,$0,$1,$1,$1,$1,$D,$1,$0
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$1,$0,$0,$0,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$0,$0,$0,$D,$1,$0
       Data.b $0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$D,$D,$D,$D,$D,$1,$0
       Data.b $0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$1,$1,$1,$1,$1,$1,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$0,$0,$1,$1,$0,$0,$0,$1,$1,$1,$1,$1,$1,$0
       Data.b $0,$0,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$D,$D,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$D,$D,$D,$0,$0,$0,$0,$0,$3,$D,$D,$3,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$1,$1,$1,$1,$D,$1,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$3,$3,$3,$3,$0,$0,$0,$1,$3,$D,$D,$3,$1,$0
       Data.b $0,$D,$1,$0,$0,$1,$1,$0,$0,$0,$0,$0,$D,$1,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$2,$1,$4,$4,$1,$2,$0,$0,$1,$3,$3,$3,$3,$1,$0
       Data.b $0,$D,$D,$D,$D,$0,$0,$0,$0,$0,$0,$0,$D,$1,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$1,$D,$D,$D,$D,$1,$0,$0,$4,$2,$2,$2,$2,$4,$0,$1,$2,$1,$4,$4,$1,$2,$1
       Data.b $0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$0,$D,$1,$1,$0,$0,$0,$D,$1,$1,$1,$D,$0,$0,$0,$0,$1,$1,$1,$D,$1,$0,$D,$0,$4,$1,$1,$4,$0,$D,$1,$4,$2,$2,$2,$2,$4,$1
       Data.b $0,$D,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$1,$0,$0,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$D,$0,$0,$0,$D,$1,$0,$0,$3,$5,$B,$B,$5,$3,$0,$0,$1,$4,$4,$4,$4,$1,$0
       Data.b $0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$D,$1,$1,$0,$0,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$1,$D,$D,$D,$1,$1,$0,$0,$0,$A,$A,$A,$A,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0
       Data.b $0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$0,$0,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$0,$1,$1,$1,$1,$0,$0,$0,$2,$0,$0,$0,$0,$2,$0,$0,$0,$0,$0,$0,$0,$0,$0
       end_texture:
       
       solid_tile:
       Data.b 1,2
       end_solid_tile:
       
       
       bin_sound_jump:
       ;  IncludeBinary "jump.wav"
       bin_sound_jump_e:
       
       bin_sound_hurt:
       ;  IncludeBinary "hurt.wav"
       bin_sound_hurt_e:
       
       bin_sound_kill:
       ;  IncludeBinary "kill.wav"
       bin_sound_kill_e:
       
       bin_sound_coin:
       ;  IncludeBinary "coin.wav"
       bin_sound_coin_e:
       
       bin_sound_falling:
       ;  IncludeBinary "falling.wav"
       bin_sound_falling_e:
       
       bin_sound_respawn:
       ;  IncludeBinary "respawn.wav"
       bin_sound_respawn_e:
       
       bin_sound_rejump:
       ;  IncludeBinary "rejump.wav"
       bin_sound_rejump_e:
       
       bin_sound_missile:
       ;  IncludeBinary "missile.wav"
       bin_sound_missile_e:
       
       bin_sound_extralife:
       ;  IncludeBinary "extralife.wav"
       bin_sound_extralife_e:
       
       
EndDataSection

Re: Petit remake d'un Mario sur Atari 7800

Publié : dim. 05/avr./2020 10:36
par MLD
Salut a tous
j'ai eu un bug ligne 905 tableau hors limite.
simplement en jouant.

Re: Petit remake d'un Mario sur Atari 7800

Publié : dim. 05/avr./2020 11:55
par G-Rom
Sympa les tuiles qui bougent ^^ , par contre ton delay 16 n'est pas pertinent , le code est ( déjà il est vraiment crado ( je parle du code de base ) :D ) , il y a une boucle ou "la physique" doit être appliqué et pas ailleurs , en effet , le code doit tourner sur les plus petite config possible , la boucle principale doit tourné à fond les ballons , la physique à 60hz suffit largement , tu as mélanger l'affichage de tuille et ("la physique") avec ton tableau global exc()
le fait de mettre un delay de 16ms reviens à activé la synchro et à brider le jeu.
Sinon, chapeau , prendre le code d'un autre pour le modifier comme tu l'a fait , mes respects ;)

Re: Petit remake d'un Mario sur Atari 7800

Publié : dim. 05/avr./2020 18:24
par Ollivier
Je n'ai plus de batterie. C'était sympa !

Re: Petit remake d'un Mario sur Atari 7800

Publié : dim. 05/avr./2020 20:16
par Ollivier
1) Le Delay(16) sert juste de bout de journal pour reboucher un trou au plâtre ! C'est pour montrer qu'il y a un trou (du temps libre) quand on utilise juste des DisplaySprite() (et transparent).

Voilà, ce n'est pas définitif. C'est pour que tu compares avec et sans GrabSprite qui, il me semble est un transfert mémoire "lent" (il me semble, au moins sur les anciennes config).



2) Il y a un champs nommé "girouette". Alors c'est loufoque le nom. C'est parceque le champs "Direction" n'est pas dans l'héritage commun, alors qu'il asservit la physique. Les mobs ne voulaient pas faire demi-tour les bougres !!



3) Le tableau Exc() (EXCeption) : là encore c'est un bon coup de bricolage dans la mécanique de ta locomotive.



Pourquoi ces rustines ? Alors que ton code est quand même rudement bien organisé.

>> R. : Il y a un bout de ta physique qui se situe de manière obscure près de la boucle principale. A mon avis, tu as dû rajouter ce bout en même temps que tu faisais à manger ou pendant que tu refaisais la toîture sous la pluie : tu as dû primer l'idée sur l'organisation initiale du code source, alors moi, bien sûr, pour rendre les dalles amovibles, j'ai, à mon tour... primé l'idée plutôt que l'organisation de ton code. Effet avalanche ! Et gros bordel assuré !!


Merci en tout cas... Beaucoup de souvenirs d'une très courte période de jeu d'une semaine, il y a plus de 20 ans où j'ai découvert ce jeu. On n'avait pas vu le temps passer...

Re: Petit remake d'un Mario sur Atari 7800

Publié : lun. 13/avr./2020 13:40
par heliuse
superbe, félicitations :)