Balloons - a Scratch tutorial written in Hollywood

The place for any Hollywood tutorials
Post Reply
User avatar
emeck
Posts: 80
Joined: Fri Apr 03, 2015 3:17 pm

Balloons - a Scratch tutorial written in Hollywood

Post by emeck » Fri Oct 11, 2019 11:48 pm

Hello,

I found a nice Scratch tutorial of a simple game and decided to make a Hollywood version. It has helped me to understand how to use sprites. I post the code here but you can get the srcipt and all other files from here in case you are interested in trying it. Please, if you have any suggestions or improvements share them so we all can learn.

Finally, thanks to jPV for suggestions, corrections and bug hunting!

Code: Select all

@APPTITLE "Balloons"
@APPAUTHOR "Enrique Mecklenburg"
@APPVERSION "$VER: Balloons 1.1 (08-Oct-19)"
@APPDESCRIPTION "Scratch example written in Hollywood"


/*********************************
*  Objective of the game is to   *
*  click on the balloons to pop  *
*  them before time ends.        *
*********************************/

@DISPLAY 1, {Width = 640, Height = 480}

@BGPIC 2, "background.png"

;balloon sprites, each with 2 frames, one with the
;balloon image and one with the popped image
@BRUSH 1, "balloon_blue.png", {LoadAlpha = True}
@BRUSH 2, "balloon_black.png", {LoadAlpha = True}
@BRUSH 3, "balloon_green.png", {LoadAlpha = True}
@BRUSH 4, "balloon_red.png", {LoadAlpha = True}

@SAMPLE 1, "pop.8svx"

EscapeQuit(True)

SetFillStyle(#FILLCOLOR)

balloons = 15          ;total ballons on screen
time = 10              ;total time in seconds
countdown = {}         ;table for storing time numbers
score = 0              ;starting score
scores = {}            ;table for storing score numbers
done = False           ;is game over?


/******************
 * Balloon object *
 ******************/
balloon = {}           ;prototype table for balloon objects

;constructor for new balloon object
Function balloon:new()    
    ;create sprite from random brush, width and height, load 2 frames and it has 2 frames per row
    o = {sprite = CreateSprite(Nil, #BRUSH, Rnd(4) + 1, 54, 70, 2, 2),
         x = 5 + Rnd(575),                          ;set balloon's initial horizontal coord
		 y = 30 + Rnd(345),                         ;set balloon's initial vertical coord
		 sx = -3 + Rnd(7),                          ;set balloon's horizontal speed
		 sy = -3 + Rnd(7),                          ;set balloon's horizontal speed
         notPopped = True}                          ;created balloon is not popped yet
    SetMetaTable(o, {__index = balloon})            ;set balloon as the "prototype" for new balloon objects
    Return(o)
EndFunction

;move balloon object
Function balloon:move()
    If self.notPopped
        ;set new position
        self.x = self.x + self.sx
        self.y = self.y + self.sy

        ;check horizontal and vertical limits
        If self.x > 586 Or self.x < 0 Then self.sx = -self.sx
	    If self.y > 410 Or self.y < 25 Then self.sy = -self.sy

        ;display sprite's frame 1 in new position
        DisplaySprite(self.sprite, self.x, self.y, 1)
    EndIf
EndFunction

;pop balloon object when hit
Function balloon:pop()
    self.notPopped = False                          ;balloon now popped
    DisplaySprite(self.sprite, self.x, self.y, 2)   ;display popped frame
    PlaySample(1)                                   ;play pop sound
    Wait(1)
    RemoveSprite(self.sprite)                       ;remove balloon sprite
EndFunction

/*** End balloon object ***/




/*******************
 * Create balloons *
 *******************/
Function p_CreateBalloons()
    For Local i = 1 To balloons
        balloon[i] = balloon:new()                  ;create new balloon object
    Next
EndFunction


/********************************************
 * Create scores and display starting score *
 ********************************************/
Function p_CreateScore()
    scoreText = CreateTextObject(Nil, "Score: ")                        ;create "Score" text

    For Local i = 0 To balloons
	    CreateTextObject(1, PadNum(i, 2))                               ;create numbers for score as text objects
	    scores[i] = CreateSprite(Nil, #TEXTOBJECT, 1)                   ;convert numbers to sprites
        FreeTextObject(1)		                                        ;free memory of no longer deeded text objects
    Next

    DisplayTextObject(scoreText, 10, 4)                                 ;display "Score" text
    DisplaySprite(scores[score], 70, 4)                                 ;display starting score
EndFunction


/**********************
 * Create time sprite *
 **********************/
Function p_CreateCountdown()
    timeText = CreateTextObject(Nil, "Time: ")                          ;create "Time" text

    For Local i = 0 To time
        CreateTextObject(1, PadNum(time - i, 2))                        ;create timer numbers as text objects starting at 10
        countdown[i] = CreateSprite(Nil, #TEXTOBJECT, 1)                ;convert numbers to sprites
        FreeTextObject(1)
    Next

    For Local i = 0 To time
        CreateTextObject(i, PadNum(time - i, 2))                        ;create timer numbers as text objects starting at 10
    Next

    DisplayTextObject(timeText, 550, 4)                                 ;display "Time" text
    DisplaySprite(countdown[0], 600, 4)                                 ;display starting time
EndFunction


/*****************
 * Move balloons *
 *****************/
Function p_MoveBalloons()
    BeginRefresh()
    For Local i = 1 To balloons
        balloon[i]:move()                                               ;move balloon object
    Next
    EndRefresh()
EndFunction


/***************************
 * Check if balloon is hit *
 ***************************/
Function p_Burst()
    Local mx, my = MouseX(), MouseY()		                            ;store mouse position when clicked

    For Local i = balloons To 1 Step -1                                 ;negative step so click works on balloon "on top" in case of overlapping with other
        If balloon[i].notPopped
            Local bx, by = balloon[i].x, balloon[i].y                   ;copy balloon position

            ;check if balloon sprite was hit
	        If mx > bx And mx < bx + 54 And my > by And my < by + 70
	            balloon[i]:pop()                                        ;remove popped balloon
                RemoveSprite(scores[score])
                score = score + 1
	            DisplaySprite(scores[score], 70, 5)                     ;update score: shows next frame of scores sprite
	            If score = balloons
		            p_GameOver()
	            EndIf
	            Break
            EndIf
        EndIf
    Next
EndFunction


/************************
 * Check time countdown *
 ************************/
Function p_Countdown()
    ;remember that time sprites run from 10 to 0
    Local t = Int(GetTimer(1) / 1000)       ;get next second

    ;when resuming after a pause, the display is redrawn and the time sprite is not in sync with the timer
    ;this checks for the sprite displayed when pausing and removes it before the next is displayed
    If t > 0
        If GetAttribute(#SPRITE, countdown[t-1], #ATTRONSCREEN) Then RemoveSprite(countdown[t-1])
    EndIf
    
    If t => time
	    DisplaySprite(countdown[t], 600, 4) ;display last time sprite (countdown[10]) which is 0
	    p_GameOver("lose")
    Else
        DisplaySprite(countdown[t], 600, 4) ;display next time sprite
    EndIf
EndFunction


/*************
 * Game over *
 *************/
Function p_GameOver(endText$)
    StopTimer(1)
    ClearInterval(2)
    ClearInterval(1)

    done = True             ;game is over

    RemoveSprites(True)     ;remove sprites but keep graphics displayed so box can be draw on top

    Box(0, 0, 640, 480, Color = #GRAY, {Transparency = "50%"})

    SetFont(#SANS, 36, {Engine = #FONTENGINE_INBUILT})
    SetFontStyle(#BOLD)
    SetFontStyle(#ANTIALIAS)

    If endText$ = "lose"
	    TextOut(#CENTER, #CENTER, "Game Over")
    Else
	    TextOut(#CENTER, #CENTER, "You won!")
    EndIf

    Wait(100)
    TextOut(#CENTER, 260, "Play again? Y/N")
EndFunction


/************
 * Clean up *
 ************/
Function p_CleanUp()
    For Local i = 0 To balloons
	    FreeSprite(scores[i])             ;free sprites created for score
    Next

    For Local i = 0 To time
	    FreeSprite(countdown[i])           ;free sprites created for timer
    Next

    For Local i = 1 To balloons
	    FreeSprite(balloon[i].sprite)     ;free sprites created for balloons
    Next

    FreeTextObject(scoreText)             ;free text objects
    FreeTextObject(timeText)

    score = 0
EndFunction


/*****************
 * Main function *
 *****************/
Function p_Start()
    done = False          ; game is not over

    SetFont(#SANS, 18, {Engine = #FONTENGINE_INBUILT})
    SetFontStyle(#BOLD)
    SetFontStyle(#ANTIALIAS)

    DisplayTransitionFX(2, {Type = #FADE, Speed = 50, Parameter = #WHITE})	;display background with a transition fx

    Box(0, 0, 640, 25, #GRAY, {Transparency = "50%"})          ;score and time area

    p_CreateScore()                                            ;set starting score
    p_CreateCountdown()                                        ;set remaining time
    Wait(25)
    p_CreateBalloons()                                         ;create and show balloons

    StartTimer(1)                                              ;start timer

    SetInterval(1, p_Countdown, 1000)                          ;execute timecountdown loop, 1 second interval
    SetInterval(2, p_MoveBalloons, 1000/25)                    ;execute main loop at 25fps
EndFunction


/***********************************
 * Check mouse and keyboard events *
 ***********************************/
Function p_EventFunction(msg)
    Switch(msg.action)
    Case "OnMouseDown":
	    If done = False
	        p_Burst()                                          ;check if balloon is hit
	    EndIf
    Case "OnKeyDown":
	    If msg.key = " " And HaveObject(#TIMER, 1)	           ;check if SPACE pressed and timer 1 is running
	        PauseTimer(1)				                       ;pause timer
	        WaitKeyDown("Space")                               ;pause the script until SPACE is pressed again
	        ResumeTimer(1)
	    ElseIf (msg.key = "Y" Or msg.key = "y") And done       ;restart if game over
	        p_CleanUp()
	        p_Start()
	    ElseIf (msg.key = "N" Or msg.key = "n") And done       ;quit if game over
	        End()
	    EndIf
    EndSwitch
EndFunction


InstallEventHandler({OnMouseDown = p_EventFunction, OnKeyDown = p_EventFunction})

p_Start()    ;start game

Repeat
    WaitEvent()
Forever
PowerBook 5.2 MorphOS 3.12
PowerBook 5.8 MorphOS 3.12
Amiga 1200 BPPC/BVision AOS4.1 FE

SantiDarkG
Posts: 11
Joined: Wed Jun 05, 2019 10:47 pm

Re: Balloons - a Scratch tutorial written in Hollywood

Post by SantiDarkG » Tue Oct 15, 2019 12:59 am

Thanks Emeck...... I will take a look. Is always awesome when somebody posted a small tutorial for newbies like me :)

User avatar
Juan Carlos
Posts: 523
Joined: Mon Sep 06, 2010 1:02 pm
Contact:

Re: Balloons - a Scratch tutorial written in Hollywood

Post by Juan Carlos » Tue Oct 15, 2019 1:31 pm

Hi, I downloaded your source example, and I have one suggestion, you can make the game for kids, shot to the balloons, change the mouse pointer for a peephole, add highscore list, different points for balloons color, etc.

User avatar
emeck
Posts: 80
Joined: Fri Apr 03, 2015 3:17 pm

Re: Balloons - a Scratch tutorial written in Hollywood

Post by emeck » Tue Oct 15, 2019 2:23 pm

@SantiDarkG
Glad you like it. I'm also learning HW and this kind of small challenges help me to learn new skills. While I was using this to play with sprites I also learnt a little about objects with LUA and HW.

I hope to share more like this.
PowerBook 5.2 MorphOS 3.12
PowerBook 5.8 MorphOS 3.12
Amiga 1200 BPPC/BVision AOS4.1 FE

User avatar
emeck
Posts: 80
Joined: Fri Apr 03, 2015 3:17 pm

Re: Balloons - a Scratch tutorial written in Hollywood

Post by emeck » Tue Oct 15, 2019 2:25 pm

@Juan Carlos
Juan Carlos wrote:
Tue Oct 15, 2019 1:31 pm
...different points for balloons color, etc.
I like that idea. Not much time available right now but I'll keep that in mind. Maybe others can improve the code meanwhile.
PowerBook 5.2 MorphOS 3.12
PowerBook 5.8 MorphOS 3.12
Amiga 1200 BPPC/BVision AOS4.1 FE

User avatar
Juan Carlos
Posts: 523
Joined: Mon Sep 06, 2010 1:02 pm
Contact:

Re: Balloons - a Scratch tutorial written in Hollywood

Post by Juan Carlos » Wed Oct 16, 2019 12:48 pm

The idea is very easy and it won't take you long, other thing is you want make a game with professional purposes, and the 75% of programming already you done, and your example is a good idea to make a game for kids, without violence.

LarsB
Posts: 56
Joined: Sat May 06, 2017 4:37 pm

Re: Balloons - a Scratch tutorial written in Hollywood

Post by LarsB » Sun Oct 20, 2019 1:58 pm

Cute! Thank you.

Post Reply