flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Examples and Tutorials > Sprite Fight Game: Animation, Sound+Music, Input

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
m3ntal



Joined: 08 Dec 2013
Posts: 296

Sprite Fight Game: Animation, Sound+Music, Input

Teaches animation, DirectSound load and play .WAV, simultaneous music+sound effects, X-Input (X360 controller) and/or keyboard, draw images inverted (to duplicate frames takes 200% memory), alpha effects, simulate shadows. Best viewed in 1366x768 resolution. Input: Move: Arrow keys, gamepad, left analog stick. Attack: A key or X button. Jump: S key or A button.

Uses sprites+music from the game Final Fight, (C) by CAPCOM (87). Many game programming students practice by using media from existing games.

Includes edited FASMW that allows optional ?if/?else/?repeat/etc for assembly directives and if/else/repeat/etc for runtime.

Download Sprite Fight

Video Preview: https://www.youtube.com/watch?v=0FJcDBSK53o


Excerpts:

Code:
  if can.jump
    if.gamepad B
      if.gamepad RIGHT
        go .jumpf
      end
      get.gamepad.lx
      if r0>4096
        go .jumpf
      end
      if.gamepad LEFT
        go .jumpb
      end
      get.gamepad.lx
      if r0<-4096
        go .jumpb
      end
      go .jumpu
    end
    if.keys S
      if.keys RIGHT
        .jumpf:
        animate playerJUMPJUMPFjumpf.a,\
         JUMP.SPEED0
        go .jumpe
      end
      if.keys LEFT
        .jumpb:
        animate playerJUMPJUMPBjumpb.a,\
         JUMP.SPEED0
        go .jumpe
      end
      .jumpu:
      animate playerJUMPJUMPUjumpu.a,\
       JUMP.SPEED0
      .jumpe:
      JUMP.HEIGHT=400
      . [player.state]=SS.JUMP
      . [player.ascend]='a'
      . r0=[player.y], [player.start.y]=r0
      . r0-JUMP.HEIGHT, [player.end.y]=r0
      go .paint
    end
  end

  if can.walk
    . walk?=NO
    . can.move.up=NOcan.move.down=NO
    . can.move.left=NOcan.move.right=NO
    . move.u=NOmove.d=NO
    . move.l=NOmove.r=NO

    if [player.y]>0
      . can.move.up=YES
    end
    . r0=[screen.h], r0-[player.h], r0-16
    if [player.y]<r0
      . can.move.down=YES
    end
    if [player.x]>0
      . can.move.left=YES
    end
    . r0=[screen.w], r0-[player.w]
    if [player.x]<r0
      . can.move.right=YES
    end

    SPEED.X=10
    SPEED.Y=8

    if can.move.up
      if.keys UP
        . move.u=YES
      end
      if.gamepad UP
        . move.u=YES
      end
      get.gamepad.ly
      if r0>4096
        . move.u=YES
      end
      if move.u
        . [player.y]-SPEED.Ywalk?=YES
      end
    end
    if can.move.down
      if.keys DOWN
        . move.d=YES
      end
      if.gamepad DOWN
        . move.d=YES
      end
      get.gamepad.ly
      if r0<-4096
        . move.d=YES
      end
      if move.d
        . [player.y]+SPEED.Ywalk?=YES
      end
    end
    if can.move.left
      if.keys LEFT
        . move.l=YES
      end
      if.gamepad LEFT
        . move.l=YES
      end
      get.gamepad.lx
      if r0<-4096
        . move.l=YES
      end
      if move.l
        . [player.x]-SPEED.Xwalk?=YES
        . [player.invert.x]=YES
      end
    end
    if can.move.right
      if.keys RIGHT
        . move.r=YES
      end
      if.gamepad RIGHT
        . move.r=YES
      end
      get.gamepad.lx
      if r0>4096
        . move.r=YES
      end
      if move.r
        . [player.x]+SPEED.Xwalk?=YES
        . [player.invert.x]=NO
      end
    end
    if walk?
      animate playerWALK0walk.a40
      go .paint
    end
  end

  ; get distance between player and enemy

  . face.enemy=NO
  . r0=[enemy.x], r1=[player.x]
  if r0<r1
    . r1-r0dx=r1
    if [player.invert.x]
      . face.enemy=YES
    end
  else
    . r0-r1dx=r0
    if not [player.invert.x]
      . face.enemy=YES
    end
  end
  . r0=[enemy.y], r1=[player.y]
  if r0<r1
    . r1-r0dy=r1
  else
    . r0-r1dy=r0
  end 

; adjectives: 1-7 scale

texts a7.ta[]= 'best''fastest''strongest',\
 'smartest''greatest''all'
texts a6.ta[]= 'better''faster''stronger',\
 'smarter''greater''most'
texts a5.ta[]= 'good''fast''strong',\
 'smart''great''more'
texts a4.ta[]= 'medium''average',\
 'normal''some'
texts a3.ta[]= 'weak''slow''dumb''less'
texts a2.ta[]= 'weaker''slower',\
 'dumber''lesser'
texts a1.ta[]= 'worst''weakest''slowest',\
 'dumbest''least''none'
                             
;;;;;;;;;;;;;;;;;;;; EFFECTS ;;;;;;;;;;;;;;;;;;;;;

; stars, explosions, lasers, projectiles

align

ARRAY effect.images[IMAGE]
integer effect.indexeffect.count

EFFECT.SPEED=1

text effect.folder='EFFECT\'  ; SPRITE\EFFECT
texts effect.files[]=\
 '1''2''3''4''5'

function load.effectsscale
  locals inimagefile
  set.sprite.folder
  set.folder effect.folder    ; \EFFECT\
  . n=effect.files.$          ; # filenames
  try @size effect.imagesn  ; allocate
 
  loop i=0 to n
    @ image=effect.images[i]
    . r0=ifile=[effect.files+r0*4]
    try load.image.t imagefile
    try size.image.p imagescale
  endl
  . [effect.index]=0, [effect.count]=0
endf 1

function draw.effectxy
  locals inimage
  . i=[effect.index]
  . n=[effect.count]
  @ image=effect.images[i]
  draw.image imagexy
  . n++
  if n>EFFECT.SPEED
    . i++
    . n=0
  end
  if i>=effect.files.$
    . i=0
  end
  . [effect.index]=i
  . [effect.count]=n
endf

; ?????????????????? SOUND.INC ???????????????????

structure SOUND
 void ss2     ; PDIRECTSOUNDBUFFER[2]
 integer status
 boolean musicreplayplayingplayed
ends ?sound

; load .wav. return PDIRECTSOUNDBUFFER

function load.wavfile
  locale wav,\
   wav.data(20),\     ; MMCKINFO
   fmt.data(20),\     ; same
   wav.format(18),\   ; WAVEFORMATEX
   ds.desc(20),\      ; DSBUFFERDESC
   sound,\            ; PDIRECTSOUNDBUFFER
   audio1audio2,\   ; circular buffers
   length1length2   ; sizes

  . r0=&wav
  memory.zero r0..locals.size

  try wav=mmioOpenA file0MMIO_ALLOCBUF

  . r0=&wav.data              ; find 'WAVE'
  . dword [r0+8]=45564157h
  mmioDescend wav,\
   r00MMIO_FINDRIFF

  . r0=&fmt.data              ; find 'fmt '
  . dword [r0+8]=20746D66h
  . r1=&wav.data
  mmioDescend wavr0r10

  . r0=&wav.format
  mmioRead wavr018
  . r0=&fmt.data
  mmioAscend wavr00
  . r0=&fmt.data              ; find 'data'
  . dword [r0]=61746164h
  . r1=&wav.data
  mmioDescend wav,\
   r0r1MMIO_FINDCHUNK

  . r0=&ds.desc      ; sound buffer description
  . dword [r0]=20    ; size
  . dword [r0+4]=224 ; flags=DSBCAPS_CTRLDEFAULT
  . r1=&fmt.data
  . r1=[r1+4]        ; fmt.data.cksize
  . dword [r0+8]=r1  ; dwBufferBytes
  . r1=&wav.format
  . dword [r0+16]=r1 ; lpwfxFormat
  . r1=&sound
  callx [dsound],\   ; CreateSoundBuffer
   12r0r10
  if true            ; error
    . sound=0
    jmp .close
  end
  . audio1=0
  . audio2=0         ; circular buffers
  push 0             ; IDirectSoundBuffer.Lock
  . r0=&length2
  push r0
  . r0=&audio2
  push r0
  . r0=&length1
  push r0
  . r0=&audio1
  push r0
  . r0=&fmt.data
  . r0=[r0+4]
  push r0
  push 0
  callx \
   soundDS.Lock
  cmp audio10      ; read from file
  jbe .us            ; write to sound buffers
  mmioRead wav,\
   audio1length1
  .us:
  cmp audio20
  jbe .us2
  mmioRead wav,\
   audio2length2
  .us2:
  callx sound,\      ; IDirectSoundBuffer.Unlock
   DS.Unlock,\
   audio1length1,\
   audio2length2
  .close:
  mmioClose wav0
endf sound

; load "sound" effect (play once) or "music"
; (replay and allow simultaneous sounds
; to be playing in the background)

function load.soundsoundfile
  try load.wav file
  . r1=sound, [?sound.s+r1]=r0
endf 1

function load.musicsoundfile
  try load.sound soundfile
  . r0=soundr1=[?sound.s+r0]
  . r2=&[?sound.s2+r0]
  . [?sound.replay+r0]=1
  callx [dsound],\
   DS.DuplicateSoundBufferr1r2
  if true
    return 0
  end
endf 1



Description:
Filesize: 250.08 KB
Viewed: 2892 Time(s)

sprite_fight.jpg




Last edited by m3ntal on 08 Mar 2014, 19:58; edited 1 time in total
Post 12 Jan 2014, 03:47
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 713

Very good example - I didn't try to compile this on my machine; how long does it take fasm to process all of your macros?
Post 12 Jan 2014, 09:59
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296

It builds fast, 1.5 seconds on my Z-Cube ITX for the library + game. See video preview.

Thanks to your examples I have decided to get back involved in game development.
Post 12 Jan 2014, 11:46
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 713

oh, that is fast. I downloaded it and played it, I just didn't try to compile it. Glad someone else is also posting game examples Very Happy
Post 12 Jan 2014, 12:43
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 5976
Location: Poland

I can't run this game on my machine with Windows 7 because it requests some functions from the 'XINPUT1_3.DLL' library.

One little remark: to make the shadows more realistic you need to slant it at some angle (SE direction for the right sprite and SW direction for the lest sprite). At least it seems to be like that accordingly to the perspective.
Post 12 Jan 2014, 14:57
View user's profile Send private message Visit poster's website Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 713

maybe I should mention this tip to m3ntal,
In my geometry wars game, in order to play in on a computer without the gamepad driver installed, I used

Code:
                     invoke  LoadLibraryA,'XINPUT9_1_0.dll'
                       test  eax,eax
                         jz  @f
                     invoke  GetProcAddress,eax,'XInputGetState'
                       test  eax,eax
                         jz  @f
                        mov  [XInputGetState],eax
                @@:  


dword[XInputGetState] initially points to an empty function so that the rest of the game doesn't crash if if any of these api calls fail.
Post 12 Jan 2014, 15:10
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 5976
Location: Poland


tthsqe wrote:
maybe I should mention this tip to m3ntal,
In my geometry wars game, in order to play in on a computer without the gamepad driver installed, I used

Code:
                     invoke  LoadLibraryA,'XINPUT9_1_0.dll'
                       test  eax,eax
                         jz  @f
                     invoke  GetProcAddress,eax,'XInputGetState'
                       test  eax,eax
                         jz  @f
                        mov  [XInputGetState],eax
                @@:  


dword[XInputGetState] initially points to an empty function so that the rest of the game doesn't crash if if any of these api calls fail.

So, the existence of those XINPUT libraries isn't crucial for the game? It's good to know. I have never used gamepad as I am not especially interested in computer games. The only exceptions I make is when I want to check what the guys from this forum can code with FASM. Wink
Post 12 Jan 2014, 15:19
View user's profile Send private message Visit poster's website Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 713

well, it of course depends on the programming, but I think any reasonable approach would not mind a call to XInputGetState not doing anything. Have you played the latest version of my geometry wars game with the keyboard? It will work whether or not xinput is installed.
Post 12 Jan 2014, 15:34
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 5976
Location: Poland


tthsqe wrote:
Have you played the latest version of my geometry wars game with the keyboard? It will work whether or not xinput is installed.

Yeah, sure, I played it, everything was OK. That's why I even didn't notice that the game can have such "exotic" libraries calls in its guts. Wink
Post 12 Jan 2014, 15:40
View user's profile Send private message Visit poster's website Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296

Updated download to use LoadLibrary. It should not need X-Input now. XINPUT_GAMEPAD structures will be all zeros. Vibration works.
Post 12 Jan 2014, 19:50
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 5976
Location: Poland


m3ntal wrote:
Updated download to use LoadLibrary. It should not need X-Input now. XINPUT_GAMEPAD structures will be all zeros. Vibration works.

Now it's OK but there was a situation when the sprite representing "Cody" went outside the screen area and there was no way to bring it back to the visible part of the screen with the cursor keys (although I could hear an action such as attack when I was pressing the A key). What can cause such a behavior? It shouldn't be a problem with the screen resolution because I have 1366x768, so what it could be?
Post 12 Jan 2014, 20:08
View user's profile Send private message Visit poster's website Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1171
Location: Unknown

Stupid post removed.


Last edited by HaHaAnonymous on 28 Feb 2015, 18:33; edited 1 time in total
Post 12 Jan 2014, 20:08
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296


Quote:
Did you make all the graphics or you took them from other games?

Again, sprites Cody+Simons are from the game Final Fight by CAPCOM (87'). You can practice game programming by using graphics+sounds from existing games. Fair use: Non-profit, educational.


Last edited by m3ntal on 04 Feb 2014, 20:24; edited 1 time in total
Post 13 Jan 2014, 10:32
View user's profile Send private message Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 340
Location: Asia, Singapore

Nice, I guess we've had enough nerdy stuff, seriously something cool
like this was required Razz
Post 13 Jan 2014, 11:35
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1230
Location: Icarian Sea


sid123 wrote:
Nice, I guess we've had enough nerdy stuff, seriously something cool


Well, the last game examples by m3ntal and tthsqe raise the bar a lot especially for poor coders like myself Razz

m3ntal it looks very cool, let alone the fact that it is written with the library-language you created. I say 'it looks', for some reason i don't know i'm getting a black screen.
Post 18 Jan 2014, 08:07
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296

Picnic: You're one of the reasons I come here. Me, you and tthsqe have different styles that are complimentary and not in opposition. We have our strengths and we can learn from each other. Once you have a good language+library, it's easy to make small games+programs in 1-3 days.

Black screen? Sad Question Idea Anyone else have this problem? Tested on 3 PCs with Win7. Screen BPP must be 32 (not 16), that would cause it.

https://www.youtube.com/watch?v=0FJcDBSK53o
Post 18 Jan 2014, 13:37
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 713

It has worked for me on every machine so far. Of course, there the slight bug that MHajduk mentioned.
Post 19 Jan 2014, 00:55
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296

tthsqe: Good.

Quote:
slight bug that MHajduk mentioned

I was aware of this when I released it (can.move/x when jumping), but do not think it's a serious issue.
Post 19 Jan 2014, 02:30
View user's profile Send private message Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 340
Location: Asia, Singapore

Wow, the source code is so awesome, that I feel I am not seeing an assembly example but a game written in powerful HLL, which is implemented through FASM Macros,
I had a similar idea of using macros to implement sort of, class-based language using macros.
Great Work! Very Happy
Just posted this under Important/Interesting Threads.
Post 19 Jan 2014, 05:10
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296

sid123: Thanks. Check this out: Z Language Manual (Unfinished).

PS: Please don't take it personal if I don't respond. I've been busy lately and haven't had much time to do programming. (Money is always the problem! See, if I had a minimal income - say $250 a week, what a McDonalds employee makes - I could afford to do programming everyday and I'd have more to give, but I'm po, meaning, way below "poor", constantly living in fear of being homeless again. In this world, one can have 1,000s of talents and never get paid).
Post 04 Feb 2014, 21:06
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2018, Tomasz Grysztar.
Powered by rwasa.