mattiasgustavsson / newpixie

Experimenting with a new version of my Pixie game dev library
77 stars 1 forks source link

Is this the Pixie lib from 2009? #3

Closed cycl0ne closed 1 year ago

cycl0ne commented 1 year ago

Hi, i found an old harddisk with code i was playing and i used alot of the pixie lib from 2009 (?). But it seems it differs alot from this new (and your old repo). Did you throw it away? i loved it in the old days and was wondering if it was still supported. The link: http://www.tophatarcade.com/dev/pixie is not working anymore.

Cheers C.

mattiasgustavsson commented 1 year ago

Yeah, that version is not something I’m supporting anymore - my understanding of code and my personal programming style have moved on quite a bit since then, and that old version is not really in a style that I would encourage anymore.

There is a newer version here https://github.com/mattiasgustavsson/pixie but that one is also obsolete in favor of this (very wip) newpixie version.

In general, I find myself moving away from engines/frameworks in favor of custom solutions for each game on top of reusable libraries (this is an example of that https://github.com/mattiasgustavsson/repair-rearm)

If you do need the old 2009 version to revive old projects, I should certainly be able to dig out the zip file - let me know if you want it. Now, whether you’ll get it to compile with modern compilers is another matter… but yeah, I don’t support it anymore

cycl0ne commented 1 year ago

Hi, no i already have it. But as I said, I really love it. Yes it maybe old. but the idea behind it is really cool. Your blitter was something i reassembled in a software blitter for my hobby os in that days. (only partly, but the src/dst/.. is still something of the best).

I never thought of it as a game library, but a library of different functions one could use. At the moment im learning alot of typescript/javascript just out of curiosity and i know what you mean with: "your personal programming style". every 5-8 years i look into some code of mine and on 50% i just think of myself: OMG ;-) But the other 50% i think: Oh wow, this is cool.

Nevertheless. Can i upload your Pixie Lib into my Repo? I know its old and you dont support it anymore, but it was very creative for me and very inspiring. dont want to get this kind of information, idea and algorithm get lost somehow.

mattiasgustavsson commented 1 year ago

That’s great to hear that it’s been useful to you 🙂 Yeah, feel free to upload it and share it however you want - I think I released it as public domain even back then.. but might be remember wrong. But anyway, do what you want with it 🙂

mattiasgustavsson commented 1 year ago

Actually, your kind words inspired me to put the last version of old pixie up as an archived repo: https://github.com/mattiasgustavsson/oldpixie Thank you!

cycl0ne commented 1 year ago

youre the best ! Believe me, for "baremetal coder" this is one real heap of cool things in there.

cycl0ne commented 1 year ago

its me again ;) i wondered why you didnt put all the examples into the archive too?

Kasandra Parachute Baby Viking Lowriderz Midwinter Poser

and the 3 Examples: 01_HelloWorld 02_BouncingBalls 03_MultiBalls

;-) Im digging in the old lib, because im learning in my old days cough TypeScript and reimplemeting some of the code form pixie into typescript ;) without the documentation of the lib (website is incomplete in archive.org) its kind of frustrating. example: the spritemanager uses originx/originy. Thats cool to seperate the sprites on screen to different parts . but why was the originx/originy in the sprite class too. making you in the spritemanager class something like this: Update(): Sprite* sprite=sprites.Get(i); float x=sprite->GetX(); float y=sprite->GetY(); sprite->SetX(x+originX); sprite->SetY(y+originY_); sprite->Render(bitmap); sprite->SetX(x); sprite->SetY(y);

and in sprite class with its own origin: Render(): GetBitmap().Blit((int)GetCel(),bitmap,(int)(GetX()-GetOriginX()),(int)(GetY()-GetOriginY()),GetColor(),GetAlpha());

So yes, some examples would be nice to be put into the pixi archive ;)

(i found on my harddisk backup: Parachute + 01,02 and 03 Sample if you need them)

mattiasgustavsson commented 1 year ago

I guess I just didn't think about the samples, but you're right, they would probably be interesting too. I have all of them, will upload to the archived repo at some point. They won't compile with the version of pixie that is uploaded though, but yeah

cycl0ne commented 1 year ago

hehe :) No thing, its more like self explaining. Digging up such a code, it helps with examples.. as i said im coding at the moment in JS/TS.. here an example, does it look familiar?😂 :

import { SpriteManager } from "./SpriteManager.js";

export class SpriteSystem {
    private static instance: SpriteSystem | null = null;
    private managers:SpriteManager[] = [];
    private defaultSpriteManager:SpriteManager | null = null;
    private constructor() {this.addSpriteManager(new SpriteManager());}

    static getInstance(): SpriteSystem {
        if (!this.instance) {
            this.instance = new SpriteSystem();
        }
        return this.instance;
    }

    update(): void {
        for (let manager of this.managers) {
            manager.update();
        }
    }

    draw(ctx: CanvasRenderingContext2D): void {
        for (let manager of this.managers) {
            manager.draw(ctx);  // Assuming the draw method of SpriteManager requires a CanvasRenderingContext2D parameter
        }
    }

    updatePriority(manager: SpriteManager):void {
        // Remove the manager from its current position
        const index = this.managers.indexOf(manager);
        if (index !== -1) {
            this.managers.splice(index, 1);
        }

        // Find the new correct position for the manager based on its priority
        let newIndex = this.managers.length; // Default to the end of the list
        for (let i = 0; i < this.managers.length; i++) {
            if (this.managers[i].getPriority() > manager.getPriority()) {
                newIndex = i;
                break;
            }
        }

        // Add the manager back into the list at its new position
        this.managers.splice(newIndex, 0, manager);
    }

    addSpriteManager(manager:SpriteManager)
    {
        const index = this.managers.indexOf(manager);

        if (index === -1) {  // Only push if it's not already in the list
            this.managers.push(manager);

            if (!this.defaultSpriteManager) {
                this.defaultSpriteManager = manager;
            }
        }

        this.updatePriority(manager);  // Update priority regardless
    }

    removeSpriteManager(manager:SpriteManager){
        const index = this.managers.indexOf(manager);
        if (index !== -1) {
            this.managers.splice(index, 1);

            // If the removed manager was the default, unset it or set a new default.
            if (this.defaultSpriteManager === manager) {
                this.defaultSpriteManager = null;
            }
        }
    }

    getSpriteManager(index: number): SpriteManager | null {
        if (index >= 0 && index < this.managers.length) {
            return this.managers[index];
        }
        return null; 
    }

    getSpriteManagerCount(): number {
        return this.managers.length;
    }

    getDefaultSpriteManager(): SpriteManager {
        if (this.defaultSpriteManager) {
            return this.defaultSpriteManager;
        } else if (this.managers.length > 0) {
            return this.managers[this.getSpriteManagerCount() - 1]; // Return the last SpriteManager from the list
        } else {
            const newManager = new SpriteManager();
            this.addSpriteManager(newManager);
            return newManager; // Return the newly created SpriteManager
        }
    }

    setDefaultSpriteManager(manager: SpriteManager): void {
        // If the manager is not already part of the system, add it.
        if (!this.managers.includes(manager)) {
            this.addSpriteManager(manager);
        }

        this.defaultSpriteManager = manager;
    }

    hasSpriteManager(manager: SpriteManager): boolean {
        return this.managers.includes(manager);
    }
}
cycl0ne commented 1 year ago

btw: i found that my pixie lib seems newer than the one you upped. I have also "Android OS" code in it. Cheers C.

mattiasgustavsson commented 1 year ago

Hmm, that must be a version modified by someone else? I don’t recall ever doing any android code…

cycl0ne commented 1 year ago

hm not sure.. all files are from 2009/2010 and was downloaded from url you commented out. from the "codingstyle" of the files.. thats not me :-)

nevertheless. can i ask you a question. as you have seen i took the concept of spritemanager/spritesystem/sprites to TypeScript and modified it for my purpose. For what was the : originX(0), originY(0), in sprite class? i threw it out, since you used it also in spritemanager.

mattiasgustavsson commented 1 year ago

Well, the origin in the sprite is to define the anchor point on the sprite. If its origin is 0,0 and its position is 100,100, the sprites top left corner will be at 100,100 on the screen. If the sprite is 64x64, and its origin is set to 32,32, then its center point would be at 100,100 on the screen instead. It’s just a convenience thing to help line things up, and it is ser separately per sprite.

The origin in the sprite manager is applied to all the sprites it manages. This is useful if you have multiple sprite managers, as you can move all sprite sthe manage, for example you might have one sprite manager holding ui, with an origin that is not moving, and another sprite manager for a scrolling playing field, where you modify its origin

cycl0ne commented 1 year ago

Ah ok understood. for the spritemanager i thought so. and indeed for my demoproject i used it like this: Spritemanager UI, Spritemanager Player, Spritemanager FOV. While im typing, i think i will extend the spritemanager by an attribute for a name, so its gets more obvious when used. And with the anchor point is really nice idea, not sure if doing it allways on blitting is efficient. at the moment i do something similar and precalculate the hotspot. But since me demo is just a turnbased game, precalc is ok, since all graphics stay static and i just use: setVisible(). Something similiar you did with your parachute game.

mattiasgustavsson commented 1 year ago

I wouldn’t worry about performance, it’s two extra additions per sprite, which is nothing compared to the cost for rendering the sprite 🙂

cycl0ne commented 1 year ago

Maybe im too old but i cant get this out of my head: "performance" 😄