Posted: 20th Aug 2011 16:21
[center]ScribbleSquash Tutorial[/center]
Video 1.0

(There are some minor sound artefacts, I need to solve, and this was performed without a script. I'm working on an updated version of this program which will be scripted and recorded later on in the future. But this will get new users up and running pretty quickly.)

[center]Flowchart[/center]
This flowchart represents the pre-loop data, and should allow users to more easily identify the variables, files and UDT's used in the making of this tutorial. This is all pre-loop stuff, but I've found lists like this useful in the past.


[center]Source Code[/center]
main.agc
+ Code Snippet
#include "mainloop.agc"
#include "gamesettings.agc"
#include "media.agc"
#include "menu.agc"

Type _obj
    img
    spr
    x#
    y#
    sx#
    sy#
    w
    h
    flag
    point
EndType

Type _media
    theme
    ball
EndType

background as _obj
logo as _obj
agk as _obj
legal as _obj
tap as _obj
court as _obj
pad as _obj
font as _obj
ball as _obj
music as _media
sound as _media

Gosub Game_Settings
Gosub Environment_Setup
Gosub Load_Music
Gosub Load_Sounds
Gosub Load_Images
Gosub Create_Sprites
Gosub Set_Sprite_Properties
Gosub Setup_Text
Gosub Menu
Gosub Randomize_Ball

Do

    Gosub Wall_Detection
    Gosub Detect_Collision
    Gosub Update_Pad
    Gosub Update_Ball
    Gosub Lives_Check

Sync()
Loop



gamesettings.agc
+ Code Snippet
Game_Settings:
    width = 1024
    height = 600
    ball.sx# = 8
    ball.sy# = 4
    mflag = 0

    speedinc# = 0.05
    Score = 0
    Lives = 3
Return

Environment_Setup:
    SetVirtualResolution( width, height )
    SetDisplayAspect( height/ width )
    SetSyncRate( 30, 0 )
Return

Randomize_ball:
    ball.x# = random( 50, width/2-50 )
    ball.y# = random( 50, height-50 )
    xflag = random( 0, 1 )
    yflag = random( 0, 1 )
Return

media.agc
+ Code Snippet
Load_Music:
    music.theme = LoadMusic("Half Bit.mp3")
    PlayMusic(music.theme, 1 )
Return

Load_Sounds:
    sound.ball = LoadSound("ball.wav")
Return

Load_Images:
    background.img = LoadImage("background.jpg")
    logo.img = LoadImage("logo.png")
    agk.img = LoadImage("AGK.png")
    legal.img = LoadImage("legal.png")
    tap.img = LoadImage("tap.png")
    court.img = LoadImage("court.png")
    ball.img = LoadImage("ball.png")
    pad.img = LoadImage("pad.png")
    font.img = LoadImage("fontdarkblue.png")
Return

Create_Sprites:
    background.spr = CreateSprite( background.img )
    logo.spr = CreateSprite( logo.img )
    agk.spr = CreateSprite( agk.img )
    legal.spr = CreateSprite( legal.img )
    tap.spr = CreateSprite( tap.img )
    court.spr = CreateSprite( court.img )
    ball.spr = CreateSprite( ball.img )
    pad.spr = CreateSprite( pad.img )
Return

Set_Sprite_Properties:
    agk.w = GetSpriteWidth(agk.spr)
    agk.h = GetSpriteHeight(agk.spr)
    SetSpriteOffSet(agk.spr, agk.w/2, agk.h/2)
    tap.w = GetSpriteWidth(tap.spr)
    tap.h = GetSpriteHeight(tap.spr)
    SetSpriteOffset(tap.spr, tap.w/2, tap.h/2)
    ball.w = GetSpriteWidth(ball.spr)
    ball.h = GetSpriteHeight(ball.spr)
    SetSpriteOffset(ball.spr, ball.w/2, ball.h/2)
    pad.w = GetSpriteWidth(pad.spr)
    pad.h = GetSpriteHeight(pad.spr)
    SetSpriteOffset(pad.spr, pad.w/2, pad.h/2)

    SetSpritePositionByOffset(agk.spr, width -(agk.w/2)-5, height-(agk.h/2)-5)
    SetSpritePositionByOffset(tap.spr, width/2, height/2+100)
    SetSpritePositionByOffset(ball.spr, width/2, height/2)
    SetSpritePositionByOffset(pad.spr, width/2 + 200, height/2)
    SetSpriteVisible(ball.spr, 0)
    SetSpriteVisible(pad.spr, 0)
    SetSpriteVisible(court.spr, 0)
Return

Setup_Text:
        SetTextDefaultFontImage( font.img )
        losttext = CreateText("")
        SetTextSize( losttext, 64 )
        SetTextAlignment( losttext, 1 )
        SetTextPosition(losttext, width/2, height/2-100)
        losttext2 = CreateText("")
        SetTextSize( losttext2, 64 )
        SetTextAlignment( losttext2, 1 )
        SetTextPosition( losttext2, width/2-32,  height/2-40)
        scoretext = CreateText("Score 0")
        SetTextSize( scoretext, 32 )
        SetTextAlignment( scoretext, 1)
        SetTextPosition( scoretext, width/4, 0)
        livestext = CreateText("Lives 3")
        SetTextPosition(livestext, (width/4)*3+32, 0)
        SetTextSize(livestext, 32)
        SetTextAlignment(livestext, 1)
        SetTextVisible(scoretext, 0)
        SetTextVisible(livestext, 0)
        SetTextVisible(losttext, 0)
        SetTextVisible(losttext2, 0)
Return

menu.agc
+ Code Snippet
Menu:

    finish = 0
    Repeat
        If y > -125
            y = y - 3
            SetSpritePosition( logo.spr, 0, y)
        EndIf
        If GetPointerPressed() = 1
            finish = 1
            SetSpriteVisible(logo.spr, 0)
            SetSpriteVisible(agk.spr, 0)
            SetSpriteVisible(legal.spr, 0)
            SetSpriteVisible(tap.spr, 0)

            SetSpriteVisible(court.spr, 1)
            SetSpriteVisible(court.spr, 1)
            SetSpriteVisible(ball.spr, 1)
            SetSpriteVisible(pad.spr, 1)

            SetTextVisible(scoretext, 1)
            SetTextVisible(livestext, 1)
            SetRandomSeed(timer())
        EndIf
    Sync()
    Until finish = 1
Return

mainloop.agc
+ Code Snippet
Wall_Detection:

    If ball.x# > width
        ball.sx# = ball.sx# + speedinc#
        ball.sy# = ball.sy# + speedinc#
        xflag = 0
        Lives = Lives - 1
        SetTextString(livestext, "Lives " + str(Lives))
        PlaySound(sound.ball)
    EndIf

    If ball.y# > height
        ball.sx# = ball.sx# + speedinc#
        ball.sy# = ball.sy# + speedinc#
        yflag = 0
        PlaySound(sound.ball)
    EndIf

    If ball.x# < 0
        ball.sx# = ball.sx# + speedinc#
        ball.sy# = ball.sy# + speedinc#
        xflag = 1
        ball.point = 0
        PlaySound(sound.ball)
    EndIf

    If ball.y# < 0
        ball.sx# = ball.sx# + speedinc#
        ball.sy# = ball.sy# + speedinc#
        yflag = 1
        PlaySound(sound.ball)
    EndIf

Return

Detect_Collision:

    If ball.flag = 1
        If GetSpriteCollision( ball.spr, pad.spr) = 1
            If xflag = 1 then xflag = 0 else xflag = 1
            ball.sx# = ball.sx# + speedinc#
            ball.sy# = ball.sy# + speedinc#
            ball.flag = 0
            If ball.point = 0
                score=score + 1
                ball.point = 1
                SetTextString( scoretext, "Score " + str(score))
            EndIf
            PlaySound(sound.ball)
        EndIf
    EndIf

    If GetSpriteCollision( ball.spr, pad.spr) = 0 then ball.flag = 1

Return

Update_Pad:
    pad.x# = GetPointerX()
    pad.y# = GetPointerY()
    If pad.x# < width/2 then pad.x# = width/2
    SetSpritePositionByOffset(pad.spr, pad.x#, pad.y#)
Return

Update_Ball:

    If xflag = 0
        ball.x# = ball.x# - ball.sx#
    Else
        ball.x# = ball.x# + ball.sx#
    EndIf

    If yflag = 0
        ball.y# = ball.y# - ball.sy#
    Else
        ball.y# = ball.y# + ball.sy#
    EndIf

    SetSpritePositionByOffset( ball.spr, ball.x#, ball.y# )

Return

Lives_Check:

    If Lives < 0
        Restart = 0
        SetTextVisible( losttext, 1)
        SetTextVisible( losttext2, 1)
        SetSpriteVisible( tap.spr, 1 )
        SetTextString( losttext, "Game Over!")
        SetTextString( losttext2, "Final Score: " + str(score))


        Repeat
            If GetPointerPressed() = 1 then Restart = 1
            Sync()
        Until Restart = 1

        width = 1024
        height = 600
        ball.sx# = 8
        ball.sy# = 4
        mflag = 0
        speedinc# = 0.05
        Score = 0
        Lives = 3
        ball.x# = random( 50, width/2-50 )
        ball.y# = random( 50, height-50 )
        xflag = random( 0, 1 )
        yflag = random( 0, 1 )
        SetTextVisible( losttext, 0)
        SetTextVisible( losttext2, 0)
        SetSpriteVisible( tap.spr, 0 )
        SetTextString(livestext, "Lives 3")
        SetTextString(scoretext, "Score 0")
    EndIf
Return
Posted: 20th Aug 2011 20:07
Great tutorial, but the music is so loud that I cannot hear you speak behind it!!
Posted: 20th Aug 2011 20:09
Thanks.I like this tutorial.
Posted: 21st Aug 2011 0:17
Cool Tutorial as always. Did wonder why the global variables were not working as I was expecting , thanks.
Posted: 21st Aug 2011 1:22
Global's need to be specified in the main.agc file, at the beginning of the file, as I understand it (and I may be wrong, feel free to correct me if anyone knows better) all variables declared outside a function, in the main.agc file are automatically global. I think my example works, because the gosubs, effectively create variables "as if" they were running from within the main.agc file. So subroutines seem to be a way of circumventing this rule.

This is all just based on my observations so far, I'm fully prepared to be wrong! This code example didn't use functions, so I may find later on that functions don't see the variables created via the subroutines. I've not put it to the test yet.

Please note that UTD's do not work in this way, and appear to need to run in the main.agc file, subroutines will not circumvent this rule.
Posted: 21st Aug 2011 5:18
Make a sticky titled "AGK Tutorials".
This way new users will be able to access them with ease

Tutorial is longer than last one. I shall enjoy it.

EDIT: What software did you use to make that flow chart? I'm doing something similar for my game.
Posted: 22nd Aug 2011 8:18
Nice tutorial . But def agree that all tutorials should be on the sticky .
Posted: 22nd Aug 2011 13:48
Excellent tutorial, learnt a few things I didn't know. The music was overpowering when you were testing and I couldn't hear your voice, perhaps next tutorial comment out the music just in case.
Posted: 23rd Aug 2011 1:29
Daniel, great tutorial, but yes the music was drowning out your voice and I had to turn down the video when you went to test your code.

You can run the music at first to show that it works then if you try to comment it out then everything should be good.
Posted: 23rd Aug 2011 3:30
Yeah the audio was dodgy as hell on that video. I'll redo the whole thing when I've got more time. Too many things to do, and CloneSprite("Daniel") doesn't work in real life.
Posted: 23rd Aug 2011 5:45
Daniel, it would be great if you could make some more tutorials, I would like to get into physics and networking and stuff like that.

In fact I wouldn't mind paying something small for your tutorials for download. Just make sure the audio is good and we are all set.
Posted: 23rd Aug 2011 13:41
Already ahead of you, I've started studying physics, once I'm confident in using it myself I'll put something up. Networking will be next on my list.
Posted: 24th Aug 2011 1:06
Excellent tutorial Daniel. Thank you.