NaaLaa
my second game, naalaa invader - Printable Version

+- NaaLaa (https://www.naalaa.com/forum)
+-- Forum: NaaLaa (https://www.naalaa.com/forum/forum-1.html)
+--- Forum: NaaLaa 7 Code (https://www.naalaa.com/forum/forum-4.html)
+--- Thread: my second game, naalaa invader (/thread-44.html)

Pages: 1 2


RE: my second game, naalaa invader - johnno56 - 02-17-2024

See? See that? See what you did? "Imagine a shootemup..." then move into a brief description.... Creative thinking! There must be a tutorial on how to do that... Formulate an idea, translate that idea into code, so that others can enjoy or understand the idea. I am amazed that you seemingly came up with that concept relatively quickly and easily. You sir, have a wonderful gift... *sigh* Well done!


RE: my second game, naalaa invader - Marcus - 02-17-2024

(02-17-2024, 07:01 PM)johnno56 Wrote: See? See that? See what you did? "Imagine a shootemup..." then move into a brief description.... Creative thinking! There must be a tutorial on how to do that... Formulate an idea, translate that idea into code, so that others can enjoy or understand the idea. I am amazed that you seemingly came up with that concept relatively quickly and easily. You sir, have a wonderful gift... *sigh* Well done!

Thank you, sir!

It didn't look quite as cool as I expected though, but this was just a quick test. Very dirty code, needs cleaning:

Code:
#win32

constant SQUARE = 24

visible enemies

set window "Square enemies", 640, 480
set redraw off

' Create a big enemy.
bigEnemy = BigEnemy()

' Create as many small enemies as there are pieces in the big enemy's shape.
enemies = []
foreach row in bigEnemy.GetShape()  foreach piece in row
    if piece  enemies[sizeof(enemies)] = SmallEnemy()
next
lastTick = clock()
while not keydown(KEY_ESCAPE, true)
    t = clock()
    dt = (t - lastTick)/1000
    lastTick = t
    
    bigEnemy.Update(dt)    
    foreach enemy in enemies enemy.Update(dt)

    set color 0, 0, 0
    cls
    foreach enemy in enemies  enemy.Draw()

    redraw
    wait 1
wend

' BigEnemy
' --------
' Return a big enemy.
function BigEnemy()
    e = []
    ' Shape of the big guy.
    e.shape = [
        [0, 0, 0, 1, 1, 1, 0, 0, 0],
        [1, 0, 1, 1, 1, 1, 1, 0, 1],
        [1, 1, 0, 1, 1, 1, 0, 1, 1],
        [0, 1, 0, 0, 1, 0, 0, 1, 0],
        [0, 1, 1, 1, 1, 1, 1, 1, 0],
        [0, 1, 1, 1, 1, 1, 1, 1, 0],
        [1, 1, 0, 1, 1, 1, 0, 1, 1],
        [1, 0, 0, 1, 0, 1, 0, 0, 1],
        [1, 1, 0, 1, 0, 1, 0, 1, 1]]
    ' True when shaped by small enemies.
    e.hasForm = false
    e.formTimer = 2
    ' Size and position.
    e.w = sizeof(e.shape[0])*SQUARE
    e.h = sizeof(e.shape)*SQUARE
    e.x = (width(primary) - e.w)/2
    e.y = (height(primary) - e.h)/2
    ' Movement.
    e.dx = 0
    e.dy = 0
    e.wdx = 0
    e.wdy = 0
    ' Get shape.
    e.GetShape = function()
        return this.shape
    endfunc
    ' Get the x position of a piece.
    e.PieceX = function(x)
        return this.x + x*SQUARE
    endfunc
    ' Get the y position of a piece.
    e.PieceY = function(y)
        return this.y + y*SQUARE
    endfunc
    ' Set a random direction.
    e.SetRandomDirection = function()
        this.turnTimer = 2 + rnd()*2
        a = rnd(360)
        this.wdx = cos(rad(a))*50
        this.wdy = sin(rad(a))*50
    endfunc
    ' Update
    e.Update = function(dt)
        ' Form.
        this.formTimer = max(this.formTimer - dt, 0)
        if this.formTimer = 0
            if this.hasForm
                this.hasForm = false
                if rnd(2) = 0
                    this.formTimer = 0.1 + rnd()*0.4
                else
                    this.formTimer = 4 + rnd()*3
                endif
            else
                this.hasForm = true
                this.formTimer = 6 + rnd()
                ' Assign positions in the shape to enemies.
                this.ShapeEnemies()
            endif
        endif
        ' Move.
        i = 1.5*dt
        this.dx = this.dx*(1 - i) + this.wdx*i
        this.dy = this.dy*(1 - i) + this.wdy*i
        this.x = this.x + this.dx*dt
        if this.x < 0  this.wdx = |this.wdx|
        elseif this.x + this.w > width(primary)  this.wdx = -|this.wdx|        
        this.y = this.y + this.dy*dt
        if this.y < 0  this.wdy = |this.wdy|
        elseif this.y + this.h > height(primary)  this.wdy = -|this.wdy|
        this.turnTimer = this.turnTimer - dt
        if this.turnTimer <= 0  this.SetRandomDirection()
        
        return true
    endfunc
    ' Assign positions in shape to enemies.
    e.ShapeEnemies = function()
        ' Uhm ... this list could be generated just once.
        positions = []
        for y = 0 to sizeof(this.shape) - 1  for x = 0 to sizeof(this.shape[0]) - 1
            if this.shape[y][x]  positions[sizeof(positions)] = [x, y]
        next
        ' Assign shape positions to enemies.
        foreach e in enemies
            if not sizeof(positions)  break
            index = rnd(sizeof(positions))
            e.SetBigEnemy(this, positions[index][0], positions[index][1])
            free key positions, index
        next
    endfunc
    
    e.SetRandomDirection()
        
    return e
endfunc

' SmallEnemy
' ----------
' Return a small enemy.
function SmallEnemy()
    e = []
    ' Its own position.
    e.selfX = rnd(640 - SQUARE)
    e.selfY = rnd(480 - SQUARE)
    ' Size.
    e.w = SQUARE
    e.h = SQUARE
    ' Movement.
    e.dx = 0
    e.dy = 0
    e.wdx = 0
    e.wdy = 0
    e.turnTimer = 0
    ' Gets set when connected to a big enemy.
    e.bigEnemy = unset
    ' Set a random direction.
    e.SetRandomDirection = function()
        this.turnTimer = 2 + rnd()*2
        a = rnd(360)
        this.wdx = cos(rad(a))*100
        this.wdy = sin(rad(a))*100
    endfunc
    ' Set big enemy.
    e.SetBigEnemy = function(bigEnemy, x, y)
        this.bigEnemy = bigEnemy
        this.bigX = x
        this.bigY = y
        this.formParam = 0
        this.formSpeed = 0.3 + rnd()*0.2
    endfunc
    ' Update.
    e.Update = function(dt)
        ' Update personal position.
        i = 1.5*dt
        this.dx = this.dx*(1 - i) + this.wdx*i
        this.dy = this.dy*(1 - i) + this.wdy*i
        this.selfX = this.selfX + this.dx*dt
        if this.selfX < 0  this.wdx = |this.wdx|
        elseif this.selfX + this.w > width(primary)  this.wdx = -|this.wdx|        
        this.selfY = this.selfY + this.dy*dt
        if this.selfY < 0  this.wdy = |this.wdy|
        elseif this.selfY + this.h > height(primary)  this.wdy = -|this.wdy|
        this.turnTimer = this.turnTimer - dt
        if this.turnTimer <= 0  this.SetRandomDirection()
        ' Combine self position with position given by big enemy.
        if this.bigEnemy
            ' Does it still have a form?
            if this.bigEnemy.hasForm
                this.formParam = min(this.formParam + this.formSpeed*dt, 1)
                p = this.formParam^2
                this.x = this.selfX*(1 - p) + this.bigEnemy.PieceX(this.bigX)*p
                this.y = this.selfY*(1 - p) + this.bigEnemy.PieceY(this.bigY)*p
            ' "explode"
            else
                a = rnd(360)
                this.wdx = this.x + this.w/2 - (this.bigEnemy.x + this.bigEnemy.w/2)
                this.wdy = this.y + this.h/2 - (this.bigEnemy.y + this.bigEnemy.h/2)
                k = 200/sqr(this.wdx*this.wdx + this.wdy*this.wdy)
                this.wdx = 0.8*this.wdx*k + 0.2*cos(rad(a))*200
                this.wdy = 0.8*this.wdy*k + 0.2*sin(rad(a))*200
                this.dx = this.wdx
                this.dy = this.wdy
                this.turnTimer = 0.25 + rnd()*0.5
                this.selfX = this.x
                this.selfY = this.y
                this.bigEnemy = unset
            endif
        ' Only use self position.
        else
            this.x = this.selfX
            this.y = this.selfY
        endif
    endfunc
    ' Draw.
    e.Draw = function()
        set color 0, 200, 0
        draw rect this.x, this.y, SQUARE, SQUARE, true
        set color 64, 255, 64
        draw line this.x, this.y, this.x + SQUARE - 1, this.y
        draw line this.x, this.y, this.x, this.y + SQUARE - 1
    endfunc
    
    e.SetRandomDirection()
    
    return e
endfunc

Sorry for hijacking your post, aliensoldier.


RE: my second game, naalaa invader - johnno56 - 02-18-2024

Cool animation! I have absolutely no idea what it could be used for but it is certainly very cool... lol


RE: my second game, naalaa invader - aliensoldier - 02-18-2024

Impressive example. The enemy is great in a list but I don't see where you are drawing it.

Okay, I create a list for my player where I draw a shape and then in the draw method with the draw rect function how could I draw that list in this function.


RE: my second game, naalaa invader - 1micha.elok - 02-21-2024

(02-17-2024, 10:56 PM)Marcus Wrote: ...

Code:
...
        ' Move.
        i = 1.5*dt
        this.dx = this.dx*(1 - i) + this.wdx*i
        this.dy = this.dy*(1 - i) + this.wdy*i
        this.x = this.x + this.dx*dt
        if this.x < 0  this.wdx = |this.wdx|
        elseif this.x + this.w > width(primary)  this.wdx = -|this.wdx|       
        this.y = this.y + this.dy*dt
        if this.y < 0  this.wdy = |this.wdy|
        elseif this.y + this.h > height(primary)  this.wdy = -|this.wdy|
        this.turnTimer = this.turnTimer - dt
        if this.turnTimer <= 0  this.SetRandomDirection()
...

...

Imagine that someday, someone will use your "dancing" BigEnemy to recreate the final chapter where THE BOSS of Space Invaders is shooting furiously and without mercy ...

    THE FINAL CHAPTER OF THE INVADERS
    Perhaps ...
    It's the final chapter of the Invaders
    You've wiped out all of the alien soldiers
    You'll meet soon the Boss
    All your strength and courage
    To the glory of the planet Earth
    ...

    DISCLAIMER 
    This is a work of fiction
    Any similarities to persons living or dead
    places or actual events is purely coincidental
    They are either the products of
    the author's imagination
    or used in a fictitious manner
    
    Press ENTER to continue  Big Grin


RE: my second game, naalaa invader - Marcus - 02-21-2024

Haha!

I was just thinking that something like this could be used in a shootemup. Smaller enemies could temporarily form larger enemies (with much higher fire power) and then continue being themselves again. Or maybe the other way around, where a big boss shatters into smaller enemies that are annoying and hard to hit.