Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
manage objects automatically
#1
I'm going to start from scratch with the last question I asked in the other forum and the answer was not very clear to me.

The code that I am going to show is made in blitzmax 1.50

Code:
Type Tpadre
    Field x:Int,y:Int;
    Global lista:TList = CreateList();
    
    'final es para que el metodo o funcion que lo lleva
    'no se pueda sobreescribir desde otra parte
    Method New() Final
        Self.lista.AddLast(Self);
    End Method
    'abstract es para que este metodo sea obligatorio
    'en todas las clases que hereden de esta
    Method pintar() Abstract;
    
    Function pintar_todo() Final
        For Local padre:Tpadre = EachIn lista
            padre.pintar();
        Next
    End Function
    
    Method eliminar() Final
        lista.Remove(Self);    
    End Method
    
    Method eliminar_todo() Final
        lista.Clear();
    End Method
    
    Method avanzar(distancia:Float,angulo:Float) Final
        Self.x:+ distancia * Cos(angulo);
        Self.y:+ distancia * Sin(angulo);
    End Method
    
    Method obtener_distancia:Float(x1:Float,y1:Float,x2:Float,y2:Float) Final
        Return Sqr((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));    
    End Method
    
    Method obtener_angulo:Float(x1:Float,x2:Float,y1:Float,y2:Float) Final    
        Return ATan2(y2-y1,x2-x1);
    End Method
         
End Type

Here it shows the parent class that has a global list, in the "new" method the objects that inherit from this class will be added automatically to the list, the "paint" method is to be used in the other classes, the "paint all" method will loop through the list and display the paint method of all objects, the "delete" method will delete an object from the list and the "delete all" method will delete all objects from the list.

The other methods are mathematical methods for different uses.

Code:
Strict;
AutoMidHandle(True);
Include "clasePadre.bmx";

                 
'jugador-----------------------------------------
Type Tjugador Extends Tpadre
    Field velocidad:Int,contador:Int;
    Field imagen:TImage = LoadImage("jugador.png");
    
    Function Create:Tjugador()
        Local jugador:Tjugador = New Tjugador;
        jugador.x = 320;
        jugador.y = 410;
        jugador.velocidad = 5;
        Return jugador;
    End Function
    
    Method pintar()
        SetRotation(0);
        Self.mover();
        Self.colision();
        Self.disparar();
        DrawImage(Self.imagen,Self.x,Self.y);
    End Method
    
    Method mover()
        If(KeyDown(KEY_LEFT) And Self.x > 32)
            Self.avanzar(Self.velocidad,180);
        ElseIf(KeyDown(KEY_RIGHT) And Self.x < 608)
            Self.avanzar(Self.velocidad,0);
        End If
        
        If(KeyDown(KEY_UP) And Self.y > 32)
            Self.avanzar(Self.velocidad,270);
        ElseIf(KeyDown(KEY_DOWN) And Self.y < 448)
            Self.avanzar(Self.velocidad,90);
        End If     
    End Method
    
    Method colision()
        If(Self.obtener_distancia(Self.x,Self.y,enemigo.x,enemigo.y) < 64)
            SetColor(255,255,0);
        Else
            SetColor(255,255,255);
        End If 
    End Method
    
    Method disparar()
        Self.contador:+1;
        If(KeyDown(KEY_Z) And Self.contador > 10)
            Tdisparo.Create(Self.x,Self.y);
            Self.contador = 0;
        End If
    End Method
    
End Type

'enemigo----------------------------------------
Type Tenemigo Extends Tpadre
    Field contador:Int;
    Field angulo:Float;
    Field imagen:TImage = LoadImage("enemigo.png");
    
    Function Create:Tenemigo()
        Local enemigo:Tenemigo = New Tenemigo;
        enemigo.x = 320;
        enemigo.y = 64;
        Return enemigo;
    End Function
    
    Method pintar()
        SetRotation(self.angulo);
        Self.angulo = Self.obtener_angulo(Self.x,jugador.x,Self.y,jugador.y);
        Self.disparar();
        DrawImage(Self.imagen,Self.x,Self.y);
    End Method
    
    Method disparar()
        Self.contador:+ 1;
        If(Self.contador > 60)
            Tdisparo2.Create(Self.x,Self.y);
            Self.contador = 0;
        End If
    End Method
    
End Type

'disparo-----------------------------------------
Type Tdisparo Extends Tpadre
    Field velocidad:Int = 5;
    Field imagen:TImage = LoadImage("disparo.png");
    
    Function Create:Tdisparo(x1:Int,y1:Int)
        Local disparo:Tdisparo = New Tdisparo;
        disparo.x = x1;
        disparo.y = y1;
        Return disparo;
    End Function
    
    Method pintar()
        SetRotation(0);
        Self.mover_eliminar();
        Self.colision();
        DrawImage(Self.imagen,Self.x,Self.y);
    End Method
    
    Method mover_eliminar()
        Self.y:- Self.velocidad;
        If(Self.y < 64)
            Self.eliminar();
        End If
    End Method
    
    Method colision()
        If(Self.obtener_distancia(Self.x,Self.y,enemigo.x,enemigo.y) < 64)
            Self.eliminar();
        End If 
    End Method
    
End Type

'disparo-----------------------------------------
Type Tdisparo2 Extends Tpadre
    Field velocidad:Int = 5;
    Field angulo:Float;
    Field imagen:TImage = LoadImage("disparo2.png");
    
    Function Create:Tdisparo2(x1:Int,y1:Int)
        Local disparo2:Tdisparo2 = New Tdisparo2;
        disparo2.x = x1;
        disparo2.y = y1;
        disparo2.angulo = disparo2.obtener_angulo(disparo2.x,jugador.x,disparo2.y,jugador.y);
        Return disparo2;
    End Function
    
    Method pintar()
        SetRotation(0);
        Self.mover_eliminar();
        Self.colision();
        DrawImage(Self.imagen,Self.x,Self.y);
    End Method
    
    Method mover_eliminar()
        Self.avanzar(Self.velocidad,Self.angulo);
        If(Self.y > 416 Or Self.x > 576 Or Self.x < 64)
            Self.eliminar();
        End If
    End Method
    
    Method colision()
        If(Self.obtener_distancia(Self.x,Self.y,jugador.x,jugador.y) < 64)
            Self.eliminar();
        End If 
    End Method
    
End Type

'------------------------------------------------
'------------------------------------------------
Graphics(640,480);

Global jugador:Tjugador = Tjugador.Create();
Global enemigo:Tenemigo =  Tenemigo.Create();


While Not KeyHit(KEY_ESCAPE)    
    'actualiza todos los objetos
    Tpadre.pintar_todo();    
    
    Flip();
    Cls();
Wend

This is the main file where I have the class player, enemy, player shot and enemy shot and they are inheriting from the parent class to use its methods.

Outside the loop we call the player and enemy objects and in the main loop we call the paint all method of the parent class that will be in charge of updating all the paint methods of the objects.

What I would like to know is how this could be done in Naalaa, I am not looking for it to be the same or similar. What I am looking for is for it to be something similar with similar results within the possibilities that Naalaa offers and for it to be as simple as possible to do.

I don't care that lists or object-oriented programming are not used, I'm just looking for something similar and if it's only with functions then perfect. I'm just looking to learn different ways to do this. If you want the code I'll upload it to try in blitzmax 1.50 which you can download here.

https://nitrologic.itch.io/blitzmax
Reply
#2
I will write an example that hopefully makes sense Smile
Reply
#3
Alright, I've attached an example Smile

I did not base it on the code you provided, easier to start from scratch.

In this example all sprites are manager by a "sprite manager". Sprites can access other sprites through the sprite manager. So, for example, player bullet sprites can get a list of all enemies from the sprite manager and do collision tests. Any sprite can remove itself or any other sprite through the sprite manager.

There's some oop style programming involved when it comes to sprites. The GreenEnemy inherits functions and data from Enemy, and Enemy inherits stuff from Sprite (the base "class").

I hope this helps! Just ask if anything is unclear Smile

And I hope that any "traditional basic programmer" looking at the code isn't scared off by all of this. I personally believe that oop and splitting your code into multiple files is "overkill" for most simple games. But when a game grows, it can certainly be useful. Use n7 however you want Big Grin

Edit: I also attached the sprite sheet generated by the Image Creator from Microsoft Bing. I picked four sprites from that one. It's an extremely handy tool that prevents me from giving up on so many projects Smile


Attached Files Thumbnail(s)
   

.zip   oop_shooter.zip (Size: 438.11 KB / Downloads: 7)
Reply
#4
I'm going to study it and tell you if I can understand it. Smile
Reply
#5
A question about the image_manager functions, I don't know exactly how useful this is, but it occurred to me that I could create a function that cycles through the images that are in the "assets" folder and then loads it into the "loadimage" function, and then make the function return that value to use it in the objects.

How could you create that images function, and the other question is if it is mandatory to free the memory of the loaded images because I am seeing the freeimages function to delete those images but I don't see it being used.
Reply
#6
(11-12-2023, 09:58 PM)aliensoldier Wrote: A question about the image_manager functions, I don't know exactly how useful this is, but it occurred to me that I could create a function that cycles through the images that are in the "assets" folder and then loads it into the "loadimage" function, and then make the function return that value to use it in the objects.

How could you create that images function, and the other question is if it is mandatory to free the memory of the loaded images because I am seeing the freeimages function to delete those images but I don't see it being used.

I've rewritten LoadAssets so that it loads all png files it can find in the assets folder.

Code:
function LoadAssets()
    ' Load images using LoadImage from image_manager. We can use GetImage in our other files to
    ' access these images.
    files = GetFiles("assets")
    foreach f in files
        ' Only load png files. The image manager automatically adds "assets/" to the path, and
        ' GetFiles returns filenames that include "assets/", so use GetFilename to remove everything
        ' but the filename (and the extension, ".png", if the second parameter is true).
        if lower(mid(f, len(f) - 4, 4)) = ".png"  LoadImage(GetFilename(f, true))
    next
endfunc

You have to add:

Code:
include "file.n7"

at the beginning of the_shooter.n7 to use the functions GetFiles and GetFilename. This library comes with n7 (it's in the N7/lib folder, so your program can always find it), but I haven't documented it.

Edit: I wrote image_manager.n7 because it was the "simplest" way of sharing image resources between multiple source code files. The FreeImages function is pretty pointless, all resources are released when the program terminates.
Reply
#7
Thanks, I'll try. Smile

I was trying to do it as I wanted and I made an example, what do you think?

Code:
function LoadImage(path,numFiles)
    array = []
    for i = 0 to numFiles
        array[i] = loadimage(path+i+".png")
    next
   
    return array
endfunc

I'm going to try to modify this function with the code you showed me and see if I can do it.

I'll give you the entire example:


Attached Files
.zip   ejemplo-imagenes.zip (Size: 100.78 KB / Downloads: 3)
Reply
#8
(11-13-2023, 05:04 PM)aliensoldier Wrote: Thanks, I'll try. Smile

I was trying to do it as I wanted and I made an example, what do you think?

Code:
function LoadImage(path,numFiles)
    array = []
    for i = 0 to numFiles
        array[i] = loadimage(path+i+".png")
    next
   
    return array
endfunc

I'm going to try to modify this function with the code you showed me and see if I can do it.

I'll give you the entire example:

Tried the example, and it seems to work good Smile
Reply
#9
I have created two examples based on the one you have shown me of oop, one with a list and the other without a list 

The one that uses the list library works fine, but the one that doesn't use the list library I can't get the trigger to be eliminated when exiting the screen. 

I show you the two examples and you can tell me where the error is or you can make a version of your example without using the list library


Attached Files
.zip   example-list.zip (Size: 12.19 KB / Downloads: 3)
.zip   example-no-list.zip (Size: 12.18 KB / Downloads: 3)
Reply
#10
I'll have a look at it tomorrow after work!
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)