Code Monkey home page Code Monkey logo

impact's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

impact's Issues

Tests?

Hey! I didn't see any tests, do you have a plan/opinion on how to start testing it?

re: "misuse of requestanimationframe"

this is regarding your (very old) blog post: https://impactjs.com/forums/impact-engine/misuse-of-requestanimationframe (it says to bring questions to this github repo)

I'm actually not using impact, but have a slow-running (on android, specifically) canvas game that I'm looking to fix up.

My current loop looks like this:

var tick = function()
{
  requestAnimationFrame(tick,canvas);
  current_scene.tick();
  current_scene.draw();
}

I'm confused what your blog post is suggesting- should I instead architect it like this:

var tick = function()
{
  current_scene.tick();
  requestAnimationFrame(draw,canvas);
}
var draw = function()
{
  current_scene.draw();
  setTimeout(tick,0);
}

?

I've tried this, and it hasn't seemed to effect performance (which is fine- my problem is likely elsewhere), but it's also irrecoverably stalled the game where it previously would just lag a bit.

I just want to make sure I'm even taking your suggestion correctly before digging more deeply into it.

Thanks!

Scroll TileSet picker in WeltMeister?

Is it possible to scroll the tileset picker when using taller tileset images? Zooming out shows the whole tileset, but too small to select the desired tile image.

ig.Font.widthForString returns (slightly) incorrect value

Screen Shot 2019-07-25 at 7 46 53 PM

// Pre-patch:
ig.game.font.widthForString('HELLO'); // 22
// Post-patch:
ig.game.font.widthForString('HELLO'); // 21
diff --git a/lib/impact/font.js b/lib/impact/font.js
index 638e91b..5d085c0 100644
--- a/lib/impact/font.js
+++ b/lib/impact/font.js
@@ -42,7 +42,10 @@ ig.Font = ig.Image.extend({
        _widthForLine: function( text ) {
                var width = 0;
                for( var i = 0; i < text.length; i++ ) {
-                       width += this.widthMap[text.charCodeAt(i) - this.firstChar] + this.letterSpacing;
+                       width += this.widthMap[text.charCodeAt(i) - this.firstChar];
+               }
+               if( text.length > 0 ) {
+                       width += this.letterSpacing * (text.length - 1);
                }
                return width;
        },

ig.DebugMapsPanel redundant 'new' keyword

var head = new ig.$new('strong');

Probably ought to be:

var head = ig.$new('strong');

I'm not even sure why the original doesn't throw an error, because all ig.$new does is

Impact/lib/impact/impact.js

Lines 110 to 111 in 6d06c28

$new: function( name ) {
return document.createElement( name );

and new (document.createElement( 'strong' )); throws JavaScript error:

Uncaught TypeError: document.createElement(...) is not a constructor

Debug Module Clocks Not Accurate?

This issue comes from: https://impactjs.com/forums/impact-engine/bug-debug-module-clocks-not-accurate

Someone correct me if I'm wrong here, but it seems that the debug module clocks are not necessarily accurate. Or at least, not what you might expect.

This is due to the order of operations that occur when classes inject/extend to and from each other.

For example, the debug module injects a clock into ig.Game:

ig.Game.inject({
    draw: function() {
        ig.graph.beginClock('draw');
        this.parent();
        ig.graph.endClock('draw');
    }
});

However, since this module is always loaded before our custom game class (lib/game/main.js), that means any modifications to draw we make in our game class won't be clocked.

MyGame = ig.Game.extend({
    // ...
    
    // this draw function wraps after the debug version
    draw: function() {
        this.parent(); // will be clocked
        this.drawGUI(); // will NOT be clocked
    }
});

The same applies to the other clocks, such as the "update" clock. It's only measuring the ig.Game.update logic, which includes updateEntities and checkEntities for example, but none of your own custom game code.

Github Version of Impact Not Up To Date?

Is the version of Impact that was uploaded to Github missing some of the later changes?

Here's a commit that shows Dominic adding a line to Input.js back in 2015:

$ git show 9333a38c
commit 9333a38c6d35f4dfd1ecc7cece5f3a7a4becfca7
Author: phoboslab <[email protected]>
Date:   Sun Oct 18 18:32:42 2015 +0200

    Release button when touch is canceled; thanks @Joncom

diff --git a/lib/impact/input.js b/lib/impact/input.js
index b1fa2fb..f9edd27 100644
--- a/lib/impact/input.js
+++ b/lib/impact/input.js
@@ -129,6 +129,7 @@ ig.Input = ig.Class.extend({
                        // Standard
                        ig.system.canvas.addEventListener('touchstart', this.keydown.bind(this), false );
                        ig.system.canvas.addEventListener('touchend', this.keyup.bind(this), false );
+                       ig.system.canvas.addEventListener('touchcancel', this.keyup.bind(this), false );
                        ig.system.canvas.addEventListener('touchmove', this.mousemove.bind(this), false );

                        // MS

However, if we look at the history for that file, the commit is not on Github...
https://github.com/phoboslab/Impact/commits/master/lib/impact/input.js

Edit: Just patched it in manually...
b8f633c

wm.Weltmeister: Should instantiate deleteLayerDialog to null

Dialogs are initialized to null:

loadDialog: null,
saveDialog: null,
loseChangesDialog: null,

However, deleteLayerDialog was missed above:

this.loadDialog = new wm.ModalDialogPathSelect( 'Load Level', 'Load', 'scripts' );

this.saveDialog = new wm.ModalDialogPathSelect( 'Save Level', 'Save', 'scripts' );

this.loseChangesDialog = new wm.ModalDialog( 'Lose all changes?' );

this.deleteLayerDialog = new wm.ModalDialog( 'Delete Layer? NO UNDO!' );

Diagonal Movement

So, I'm not sure if this is the place to ask for help, but the forum redirected me here. I'm attempted to make a top-down game. I have movement for UP, LEFT, RIGHT, and DOWN, but I'm attempting to do Diagonal movement. The code I have so far is this:

    //DIAGONAL-UP-RIGHT ATTEMPT//
    else if(ig.input.state('up') && ig.input.state('right')) {
      this.vel.y = -this.speed;
      this.vel.x = +this.speed;
    }

Seeemed logical to me, but unfortunately it didn't work. Any advice?

ig.Font.height value is incorrect

Screen Shot 2019-07-25 at 6 49 36 PM

I've always found it a little strange that a pixel art centric game engine reports incorrect values when dealing with the pixel font class.

font.getHeightForString('Hello'); <-- incorrect value
font.height <-- also incorrect

For example, using the default font that comes with Impact:

font.height returns 9

It (kind of?) makes sense, because the image itself is that tall.

But really the font should report 7, because the bottom two lines contain no visual font data...

Ie. One line is empty space, and the other line represents character widths.

ig.Debug.addNumber 'width' argument unused

showNumber takes a width argument which gets passed into addNumber

showNumber: function( name, number, width ) {
if( !this.numbers[name] ) {
this.addNumber( name, width );
}
this.numbers[name].textContent = number;
},

... which ultimately never gets used for anything.

addNumber: function( name, width ) {
var number = ig.$new('span');
this.numberContainer.appendChild( number );
this.numberContainer.appendChild( document.createTextNode(name) );
this.numbers[name] = number;
},

Furthermore, no showNumber calls ever bother to pass in width in the first place...

this.showNumber( 'ms', this.debugTime.toFixed(2) );
this.showNumber( 'fps', Math.round(1000/this.debugTickAvg) );
this.showNumber( 'draws', ig.Image.drawCount );
if( ig.game && ig.game.entities ) {
this.showNumber( 'entities', ig.game.entities.length );
}

Stop forcing single-channel audio in ig.Music?

Impact/lib/impact/sound.js

Lines 239 to 249 in 3b6d3b5

// Did we get a WebAudio Source? This is suboptimal; Music should be loaded
// as HTML5 Audio so it can be streamed
if( track instanceof ig.Sound.WebAudioSource ) {
// Since this error will likely occour at game start, we stop the game
// to not produce any more errors.
ig.system.stopRunLoop();
throw(
"Sound '"+path+"' loaded as Multichannel but used for Music. " +
"Set the multiChannel param to false when loading, e.g.: new ig.Sound(path, false)"
);
}

As the above snippet mentions, an advantage to using "HTML5 Audio" for music, is that it the audio can be streamed. And Impact enforces this preference by throwing an error.

However, I can think of at least one advantage to allowing "Web Audio" to be used...

Getting sounds to play at all in mobile browsers is a bit finicky:

To prevent annoying ads during mobile web browsing, all sounds are always disabled by default (on iOS Safari at least), until at least one sound has been played in the actual callback of a touchend event, which can only triggered by the user himself.

With "Web Audio", the solution is easy:

In the case of "Web Audio", playing a single sound in this callback will enable all other and future "Web Audio" playback. Playing one sound enables all the others.

However, with "HTML Audio", it's more cumbersome:

Each and every individual sound file must be played in this callback, to enable each one for future playback.

Here is the basic solution to get audio enabled on mobile browsers:

ig.system.canvas.addEventListener('touchend', function() {
    if( !ig.game.mobileAudioEnabled ) {
    
        // Playing a single "Web Audio" source will enable all others
        ig.game.silent.play();
        ig.game.silent.stop();

        // Each "HTML5 Audio" source much be enabled invididually
        for(var i=0; i<ig.game.tracks.length; i++) {
            ig.game.tracks[i].play();
            ig.game.tracks[i].stop();
        }

        ig.game.mobileAudioEnabled = true;
    }
}, false);

Although this works to enable all sounds, it has 2 issues:

  1. Brief laggy moment when sounds first enable (noticeable FPS jitter)
  2. The tracks in ig.game.tracks can be heard for a split second

If ig.Music were modified to allow tracks to be "Web Audio" instead of "HTML5 Audio", I think issues 1 and 2 would both be resolved.

ig.system.canvas.addEventListener('touchend', function() {
    if( !ig.game.mobileAudioEnabled ) {
        ig.game.silent.play();
        ig.game.silent.stop();
        ig.game.mobileAudioEnabled = true;
    }
}, false);

Just thinking out loud here... Maybe it would be an idea to allow both types of audio for music, so that if streaming is important, that works, and if streaming is not important but support for mobile audio is, that option works a bit nicer too.

Edit:

Hmm. I just noticed there's actually already some audio unlock logic in sound.js:

document.addEventListener('touchstart', this.boundWebAudioUnlock, false);
}
},
unlockWebAudio: function() {
document.removeEventListener('touchstart', this.boundWebAudioUnlock, false);
// create empty buffer
var buffer = this.audioContext.createBuffer(1, 1, 22050);
var source = this.audioContext.createBufferSource();
source.buffer = buffer;
source.connect(this.audioContext.destination);
source.start(0);
},

However, this logic does not work, which is why I came up with my own unlock logic in the first place.

But the follow patch fixes it:

diff --git a/lib/impact/sound.js b/lib/impact/sound.js
index 50d74be..afcc7a4 100644
--- a/lib/impact/sound.js
+++ b/lib/impact/sound.js
@@ -34,13 +34,13 @@ ig.SoundManager = ig.Class.extend({
                if( ig.Sound.enabled && ig.Sound.useWebAudio ) {
                        this.audioContext = new AudioContext();
                        this.boundWebAudioUnlock = this.unlockWebAudio.bind(this);
-                       document.addEventListener('touchstart', this.boundWebAudioUnlock, false);
+                       ig.system.canvas.addEventListener('touchstart', this.boundWebAudioUnlock, false);

                }
        },

        unlockWebAudio: function() {
-               document.removeEventListener('touchstart', this.boundWebAudioUnlock, false);
+               ig.system.canvas.removeEventListener('touchstart', this.boundWebAudioUnlock, false);

                // create empty buffer
                var buffer = this.audioContext.createBuffer(1, 1, 22050);

As far as I can tell though, Impact still has no "audio unlock" for HTML5 audio...

ig.ua.mobile Not Working in Chrome on iOS

Hello.

It appears that ig.ua.mobile is no longer working on Chrome on iOS.

Now the buttons won't draw().

I was thinking about just checking for screen width... Maybe that's a more resilient method.

Creating an named entity in WM, then undoing, then redoing, throws error

Steps to reproduce:

  1. Load any level
  2. Create some entity
  3. Give the entity a name property of any string, such as "player"
  4. Delete the entity by pressing "Z" to undo the entity creation
  5. Press "Y" to redo the entity creation

An error was thrown in console.

This line:

this.namedEntities[action.entity.name] = action.entity;

Should be:

ig.game.entities.namedEntities[action.entity.name] = action.entity;

Because wm.Undo has no namedEntities object...

ig.BackgroundMap drawing unnecessary chunks off-screen

I think there might be a bug in impact.background-map, which causes it to sometimes draw wastefully when pre-rendering is turned on.

Let's assume:

  • the canvas is 1280 x 720
  • the chunk size is the default 512
  • the camera (ig.game.screen) is at 0, 0
  • the map has a total pixel width of 1216 pixels
  • the map repeats

Chunks will be drawn from left to right...

  1. The 1st chunk is drawn to x=0, y=0
  2. The 2nd chunk is drawn to x=512, y=0
  3. The 3rd chunk is drawn to x=1024, y=0
  4. The 4th chunk is drawn at x=1216, y=0 because the 3rd chunk was only 192 pixels wide (1216 - 1024 = 192), triggering the following code to execute, incrementing maxChunkX, and therefore drawing an extra chunk to fill the remaining area, as was intended:
// If we repeat in X and this chunk's width wasn't the full chunk size
// and the screen is not already filled, we need to draw anohter chunk
// AND nudge it to be flush with the last chunk
if( this.repeat && chunk.width < this.chunkSize && x + chunk.width < ig.system.realWidth ) {
	nudgeX += this.chunkSize - chunk.width;
	maxChunkX++;
}

The problem however, is that this maxChunkX++ increments for every row, so when the 2nd row is drawn, 1 chunk will drawn unnecessarily, completely off screen to the right. And as the 3rd row is drawn, now 2 unnecessary draws. The 4th row, 3 unnecessary draws. And so on and so forth.

Is there any way to edit images?

Is there any way to edit images, like merge two images together and return a new image instance, or replace certain colours in an image to another colour?

Selenium/Appium compatibility

So, I once had to write some integration tests for a game made with impact.js. I didnโ€™t create the game nor had I any knowledge of impact.

For these tests I was using Selenium and Appium. With Selenium I tried to click simple buttons inside the game. To my suprise that was not working. And at this point Iโ€™d just want to know if I judged the issue correctly and if there is a better workaround.

I wasnโ€™t able to use Seleniums click method because the element I wanted to interact with was expecting something called ig.touchEvent. And as far as I understood the way Selenium works, is that it sends an HttpRequest to the browser to execute the according event, but since this event is not native to any browser Selenium could not do so? Thatโ€™s atleast my explanation. My workaround for this was to simply the trigger this event on the according element through javascript, which works fine.

So is there another explanation and workaround for this case?

Remove ig.Entity._wmInEditor property?

newEntity._wmInEditor = true;

As far as I can tell this doesn't get used anywhere...

Furthermore, there are other ways of detecting if the editor is running:

if( ig.global.wm ) { /* running weltmeister */ }
if( ig.editor ) { /* running weltmeister */ }

Is there really any need to add this information to every single entity?

Impossible to make multiple instances of ig.Font that share common image path

Say, for example, you wanted to create two instances of ig.Font, both which share the same image: 'media/04b03.font.png'

MyGame = ig.Game.extend({

	font1: new ig.Font( 'media/04b03.font.png' ),
	font2: new ig.Font( 'media/04b03.font.png' ),
	
	draw: function() {
		this.parent();

		var x = ig.system.width/2,
			y = ig.system.height/2;
		
		this.font1.draw( 'It Works 1!', x, y, ig.Font.ALIGN.CENTER );
		this.font2.draw( 'It Works 2!', x, y + 10, ig.Font.ALIGN.CENTER );
	}
});

download

Then let's say you want to modify the letter spacing of one, but not the other...

Sep-15-2019 01-01-49

It's not possible. Modifying one font instance, modifies the other, because they are the same instance. You can't have more instances, due to the way ig.Image caching works.

This works great for images, but not necessarily for fonts.

Perhaps it would make sense for ig.Font to be its own class, and simply have an image property which it reads from, instead of extending from ig.Image.

Need help in understanding..

What is wrong with my code? I can't spawn a button entity from the init function of another entity.

ig.module(
'game.entities.HomeScreen'
)
.requires(
'impact.entity',
'plugins.button'
)
.defines(function(){

    HomeScreen = ig.Entity.extend({


        size: {x: 1915, y: 1080},
        animSheet: new ig.AnimationSheet( 'media/game_assets/landing_screen/bg.jpg', 1915, 1080),
        rulesBtn: null,

        init: function( x, y, settings ) {

            this.parent( x, y, settings );
            this.addAnim('idle', 1, [0]);

            this.spawnHUD();
        },

        spawnHUD: function () {


            this.rulesBtn = ig.game.spawnEntity(Button, 100, 100, {

                id:  'rules',
                name: 'rules_btn',
                animSheet: new ig.AnimationSheet( 'media/game_assets/landing_screen/rules.png', 621, 170),

                pressedUp: function(){
                    console.log('Pressed Up!');
                }
            });
        }
    });
});

Deleting an named entity in WM, then undoing, throws error

Steps to reproduce:

  1. Load any level
  2. Select some entity
  3. Give the entity a name property of any string, such as "player"
  4. Delete the entity
  5. Press "Z" to undo

An error was thrown in console.

This issue affects the "redo" code as well.

The reason this happens is because when a deleted entity has a name, this code gets executed when you undo the deletion:

this.namedEntities[action.entity.name] = action.entity;

And there is no property called namedEntities in this class.

Collision FIXED on both entities

Hi, I'm trying to implement a roaming enemy or npc entities which stops the player when collided and vice versa. How do I go about this? If I set FIXED on both player and npc, the npc still slides away when collided.

ig.Loader requires unnecessary modules?

.requires(
'impact.image',
'impact.font',
'impact.sound'
)

As far as I can tell, none of these are actually used within the ig.Loader class/module...

Edit:

It's for sure possible to have a game that doesn't use any ig.Font, but by requiring it here, the font code will still get baked into the final output, unnecessarily.

One could argue that some of those required modules do get used in the loader, because they are populated into the resources array, and then manipulated via methods such as .load...

Fix mobile browser audio unlock

diff --git a/lib/impact/sound.js b/lib/impact/sound.js
index 50d74be..afcc7a4 100644
--- a/lib/impact/sound.js
+++ b/lib/impact/sound.js
@@ -34,13 +34,13 @@ ig.SoundManager = ig.Class.extend({
                if( ig.Sound.enabled && ig.Sound.useWebAudio ) {
                        this.audioContext = new AudioContext();
                        this.boundWebAudioUnlock = this.unlockWebAudio.bind(this);
-                       document.addEventListener('touchstart', this.boundWebAudioUnlock, false);
+                       ig.system.canvas.addEventListener('touchstart', this.boundWebAudioUnlock, false);

                }
        },

        unlockWebAudio: function() {
-               document.removeEventListener('touchstart', this.boundWebAudioUnlock, false);
+               ig.system.canvas.removeEventListener('touchstart', this.boundWebAudioUnlock, false);

                // create empty buffer
                var buffer = this.audioContext.createBuffer(1, 1, 22050);

modernized Impact

Hi,

a few month ago, i forked Impact and tried to move it to the shiny new world of javascript.

  • completely removed the custom ig.Class
  • moved to webpack to pack everything
  • added eslint

and to simplify everything, i wrote a small cli, to bootstrap new impact projects and running weltmeister out of the box

want to take a look at it? i also made a demo gif for a short overview ;)

https://github.com/cdreier/Impact

perhaps a chance to merge it?

Using deprecated mousewheel event

The engine uses: https://developer.mozilla.org/en-US/docs/Web/API/Element/mousewheel_event

var delta = event.wheelDelta ? event.wheelDelta : (event.detail * -1);

var delta = event.wheelDelta ? event.wheelDelta : (event.detail * -1);

which is apparently deprecated

This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible

and non-standard

This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.