my second game, naalaa invader johnno56 Senior Member Posts: 252 Threads: 27 Joined: Nov 2023 Reputation: 3 02-17-2024, 07:01 PM 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! Logic is the beginning of wisdom. Marcus Administrator Posts: 272 Threads: 34 Joined: Nov 2023 Reputation: 3 02-17-2024, 10:56 PM (This post was last modified: 02-17-2024, 11:04 PM by Marcus.) (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. johnno56 Senior Member Posts: 252 Threads: 27 Joined: Nov 2023 Reputation: 3 02-18-2024, 02:02 AM Cool animation! I have absolutely no idea what it could be used for but it is certainly very cool... lol Logic is the beginning of wisdom. aliensoldier Member Posts: 79 Threads: 15 Joined: Nov 2023 Reputation: 2 02-18-2024, 09:57 PM 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. 1micha.elok Member Posts: 159 Threads: 17 Joined: Nov 2023 Reputation: 0 02-21-2024, 01:44 AM (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  Marcus Administrator Posts: 272 Threads: 34 Joined: Nov 2023 Reputation: 3 02-21-2024, 06:23 AM 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. « Next Oldest | Next Newest »