PHASER ALTARA Struggling with motion paths, enemy ai and animations - animation

Basically I want to make my sprite follow a motion path and depending on its direction it is going, it will play a particular animation. i.e. moving up will display its back, moving left will display the left side of the sprite and so on.
I've tried for hours but to no avail in trying to make this work. I had some luck using prototype but the final game will be using the structure below. ANY help will be appreciated.
/*
* initalise Phaser framework with width:960px, height:540px
*/
var game = new Phaser.Game(960, 540, Phaser.AUTO, 'gameContainer', { preload: preload, create: create, update: update, });
/*
* Preload runs before the game starts. Assets such as images and sounds such be preloaded here.
* A webserver is required to load assets.
*
* Also in this function we set game scale so it full browser width.
*/
function preload() {
// set to scale to full browser width
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.parentIsWindow = true;
//set the background color so can confirm the game renders in the browser
this.stage.backgroundColor = '#4488cc';
this.game.renderer.renderSession.roundPixels = true;
//preload images & sounds
//game.load.image('key', 'folder/filename.png');
//this.load.image('nazi', 'image/nazi.png');
game.load.spritesheet('nazi', 'images/nazi.png', 128, 128, 6);
this.bmd = null;
this.alien = null;
this.mode = 0;
//Use this website to set enemy movements http://phaser.io/waveforms. Export save data from the console log.
this.points = {
"type":0,"closed":true,"x":[120,120,260,260,200,180,120],"y":[368,108,108,308,308,368,368]
};
this.pi = 0;
this.path = [];
}
/*
* Add game variables here
*/
var nazi;
/*
* Create runs once only when Phaser first loads
* create the game scene by adding objects to the stage
*/
function create() {
bmd = this.add.bitmapData(this.game.width, this.game.height);
bmd.addToWorld();
/*
For testing
this.alien = this.add.sprite(0, 0, 'alien');
this.alien.anchor.set(0.5);
*/
this.nazi = this.add.sprite(0, 0, 'nazi');
this.nazi.anchor.set(0.5);
var py = this.points.y;
/*Original Code
//define the animation
nazi.animations.add('walk');
//start the animation at 30fps
nazi.animations.play('walk', 3, true);
*/
//define the animation
this.nazi.animations.add('walkDown', [2, 3]);
//start the animation at 30fps
this.nazi.animations.play('walkDown', 3, true);
//define the animation
this.nazi.animations.add('walkLR', [4, 5]);
//start the animation at 30fps
this.nazi.animations.play('walkLR', 3, true);
//define the animation
this.nazi.animations.add('walkUp', [0, 1]);
//start the animation at 30fps
this.nazi.animations.play('walkUp', 3, true);
}
function plot() {
this.bmd.clear();
this.path = [];
/*ROTATION CODE*/
var ix = 0;
/**/
//Sets the speed of the sprite
var x = 0.5 / game.width;
//looping through plotting points from x and y array
for (var i = 0; i <= 1; i += x) {
var px = this.math.linearInterpolation(this.points.x, i);
var py = this.math.linearInterpolation(this.points.y, i);
/* ROTATION CODE to follow direction of path*/
var node = { x: px, y: py, angle: 0 };
if (ix > 0)
{
node.angle = this.math.angleBetweenPoints(this.path[ix - 1], node);
}
this.path.push(node);
ix++;
/**/
//this.path.push( { x: px, y: py });
this.bmd.rect(px, py, 1, 1, 'rgba(255, 255, 255, 1)');
}
for (var p = 0; p < this.points.x.length; p++) {
this.bmd.rect(this.points.x[p]-3, this.points.y[p]-3, 6, 6, 'rgba(255, 0, 0, 1)');
}
}
/*
* Update runs continuously. Its the game loop function.
* Add collision detections and control events here
*/
function update() {
plot();
// Reset the players velocity (movement)
//this.nazi = 'nazi';
/* For Testing
this.alien.x = this.path[this.pi].x;
this.alien.y = this.path[this.pi].y;
//ROTATION CODE:
this.alien.rotation = this.path[this.pi].angle;
*/
this.nazi.x = this.path[this.pi].x;
this.nazi.y = this.path[this.pi].y;
//this.nazi.rotation = this.path[this.pi].angle;
this.pi++;
if (this.pi >= this.path.length)
{
this.pi = 0;
}
/*
// Flipping the player image based on the velocity
if(nazi.body.velocity.x > 0){
//player is moving right
nazi.scale.x = -1;
nazi.animations.play('walkLR');
}
else if(nazi.body.velocity.x < 0){
//player is moving left
nazi.scale.x = 1; //flip the image
nazi.animations.play('walkLR');
}
else if (nazi.body.velocity.y < 0){
nazi.animations.play('walkUp');
}
else if(nazi.body.velocity.y > 0){
//player is not moving
nazi.animations.play('walkDown');
}
*/
}

Related

Is adding the new data point not at the end of array a bad idea?

This involves a design decision. An interviewer asked me to write something to plot the data assuming there are 100 data points, and new data point comes in (and given to the program) every 0.1, 0.3 or 0.5 or 1 second. (it can change in the future, and I think the smallest granularity on a common web browser is 0.03 seconds).
I proceeded to think about adding the new data point to the Nth position in the array. For example, adding the data at array entry 36, and plot the data from 37th to 99th, and then from 0th to 36th. Next time, add the data at array entry 37, and plot the data from 38th to 99th, and then from 0th to 37th.
This way, we don't need to "unshift" (shift out) the data at entry 0 and therefore needing to shift entry 1 to 99 one place forward, and then add the new data point at entry 99, and then plot data entry 0 to 99.
For some reason, the interviewer gave a big frown, and said, "why would we do that? It is not heavy to shift 99 data over." I said what if there are 500 or 1000 data point we'd like to plot in the future, we might want to avoid shifting data about 500 times or 1000 time each time when a new data point comes in.
He mentioned "let's say we just shift them anyway".
Is shifting the data actually not an issue or concern? What if on the screen we have 10 or 15 of such widgets, apps, or webpages, to monitor 15 types of data, we might want to avoid shifting 15,000 data entries constantly.
I naively tried to load n canvas to the page, and compared the time needed to plot against the time taken shifting array.
tldr: Whichever method is used to shift the points, the method is negligible against the time needed to plot the points. (~ 3%)
I only run the code in ff70 with casual js.
(For instance I am stocking an array of objects even though optimization may be available if I stock only floats)
There are two kind of measures: push and refresh.
push measures the time needed to shift a point and add a new one
refresh measures the time needed to replot the canvas
Below three approaches for pushing: either push (Array.prototype.(shift|push), tail to a queue (and move the head), or nopole's approach
Every 10ms I plot the time spent in the push method. On top of the picture, the cumulative time spent. I stop once a run has reached 100 points and reload the page for another run.
The y axis is the same accross all runs
Push
push avg: (838+886+864)/3 = 862ms
Queue
push avg: (625+760+825)/3 = 736ms
refresh avg: (40554+39934+40915+39194+39264+30480)/6 = 38390ms
Nopole
push avg: (792+861+871)/3 = 841ms
Notice that for one sample: (625/30480) we seem to have benefited from some cpu willing to work. So the shifting method feels even more irrelevant.
It is hard to tell which approach is better, because of the few samples drought for each kind of methods and it is likely more an issue of cpu's overall workload rather than the page itself
To reproduce
let timerPush = 0
let timerRefresh = 0
class Canvas {
constructor (f, el, period) {
this.w = 300
this.h = 300
this.points = []
const canvas = document.createElement('canvas')
canvas.style.cssText = 'background:#eeeeee; margin:10px;'
canvas.width = this.w
canvas.height = this.h
this.ctx = canvas.getContext('2d')
this.ctx.transform(1, 0, 0, -1, 0, this.h / 2)
this.ctx.lineWidth = 1
this.dw = this.w / this.MAX_POINTS
this.dh = this.h / 2
el.appendChild(canvas)
let x = 0
this.timer = setInterval(_ => {
x += period
this.push({ x, y: f(x) })
this.refresh()
}, period * 1000)
}
refresh () {
const now = performance.now()
this.ctx.clearRect(0, -this.h / 2, this.w, this.h)
this.ctx.beginPath()
this._plot()
this.ctx.stroke()
this.ctx.closePath()
timerRefresh += performance.now() - now
}
push (p) {
const now = performance.now()
this._push(p)
timerPush += performance.now() - now
}
_plot () {
if (!this.points.length) { return }
this.ctx.moveTo(0 * this.dw, this.points[0].y * this.dh)
for (let i = 1; i < this.points.length; ++i) {
const p = this.points[i]
this.ctx.lineTo(i * this.dw, p.y * this.dh)
}
}
_push (p) {
if (this.points.length == this.MAX_POINTS) {
this.points.shift()
}
this.points.push(p)
}
MAX_POINTS = 100
}
class CanvasQueue extends Canvas {
constructor () {
super(...arguments)
this.tail = {}
this.head = this.tail
this.n = 0
}
_plot () {
if (!this.head.next.p) return
let node = this.head.next
this.ctx.moveTo(0 * this.dw, node.p.y * this.dh)
let i = 1
node = node.next
while (node) {
this.ctx.lineTo(i * this.dw, node.p.y * this.dh)
++i
node = node.next
}
}
_push (p) {
if (this.n === this.MAX_POINTS) {
this.head = this.head.next
} else {
this.n++
}
const node = { p }
this.tail.next = node
this.tail = node
}
}
class CanvasNopole extends Canvas {
constructor () {
super(...arguments)
this.start = 0
}
_plot () {
if (!this.points.length) { return }
const s = this.start
let z = 1
let startBack = 0
if (this.points[s]){
this.ctx.moveTo(0 * this.dw, this.points[s].y * this.dh)
for (let i = s+1; i < this.points.length; ++i) {
const p = this.points[i]
this.ctx.lineTo(z++ * this.dw, p.y * this.dh)
}
}else{
this.ctx.moveTo(0 * this.dw, this.points[0].y * this.dh)
startBack = 1
}
for (let i = startBack; i < s; ++i) {
const p = this.points[i]
this.ctx.lineTo(z++ * this.dw, p.y * this.dh)
}
}
_push (p) {
this.points[this.start] = p
this.start = (this.start + 1) % this.MAX_POINTS
}
}
class CanvasSummary extends Canvas {
constructor () {
super(...arguments)
this.ctx.resetTransform()
this.ctx.transform(1, 0, 0, -1, 0, this.h)
// we know beforehand that timer should not grow bigger
const deltaTimer = 50
this.dh = this.h / deltaTimer
this.old = timerPush
}
refresh () {
this.ctx.clearRect(0, 0, this.w, this.h)
this.ctx.beginPath()
this.ctx.resetTransform()
this.ctx.fillText(`push: ${timerPush} plot: ${timerRefresh}`, 5, 20)
this.ctx.transform(1, 0, 0, -1, 0, this.h)
this._plot()
this.ctx.stroke()
this.ctx.closePath()
}
push (p) {
this._push(p)
}
}
function run () {
const $summary = document.querySelector('.summary')
const $bench = document.querySelector('.bench')
const cs = new CanvasSummary(x => {
if (cs.points.length === cs.MAX_POINTS) {
clearInterval(cs.timer)
}
const y = timerPush - cs.old
cs.old = timerPush
return y
}, $summary, 1)
//const canvas = Array(30).fill(0).map(x => new Canvas(Math.sin, $bench, 0.01))
//const canvas = Array(30).fill(0).map(x => new CanvasQueue(Math.sin, $bench, 0.01))
const canvas = Array(30).fill(0).map(x => new CanvasNopole(Math.sin, $bench, 0.01))
}
run()
<section class="summary"></section>
<hr/>
<div class="bench"></div>

Is there any solution to Firefox 37's poor Canvas rendering performance

I've deliberately provided the version number in the question as this is the kind of question that will go out of date at some point.
Here is a simple animation that will run perfectly smoothly in Chrome and Safari, but will be very jerky in Firefox:
function lerp(a,b,λ) {
return a + λ*(b-a);
}
function random(a,b) {
return lerp( a, b, Math.random() );
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
$(document).ready( function()
{
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var balls = new Array(12);
for( var i=0; i<balls.length; i++ )
{
while(true)
{
var density = Math.sqrt( random(1,100) );
var r = random(5, 30);
var x = random( r+1, canvas.width-1 -(r+1) ),
y = random( r+1, canvas.height-1 -(r+1) );
var overlap = false;
for( var j=0; j<i; j++ )
{
var _x = balls[j].x - x,
_y = balls[j].y - y,
d2 = _x*_x + _y*_y,
_r = balls[j].r + r;
if( d2 < _r*_r )
overlap = true;
}
if( overlap )
continue;
balls[i] = {
color : d3.hsl( lerp(0,240,density/10), random(.3,.7), random(.3,.7) ).toString(),
x : x,
y : y,
vx : random(0, 0.2),
vy : random(0, 0.2),
r : r,
advance: function(t) {
this.x += t * this.vx;
this.y += t * this.vy;
}
};
break;
}
};
window.requestAnimationFrame(vsync);
var t_last;
function vsync(t)
{
if( t_last )
render( t - t_last );
t_last = t;
window.requestAnimationFrame(vsync);
}
function render(t_frame)
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle="gray";
ctx.fillRect(0,0, canvas.width, canvas.height);
function advance_all(t) {
balls.forEach( function(b) {
b.advance(t);
});
}
var t_remaining = t_frame;
while(true) {
var hit = get_next_collision( balls, canvas.width, canvas.height );
if( t_remaining < hit.t )
break;
advance_all( hit.t );
t_remaining -= hit.t;
collide_wall( balls[hit.i], hit.wall );
balls[hit.i].advance(.001);
};
advance_all( t_remaining );
// draw balls
balls.forEach( function(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2, true);
ctx.closePath();
ctx.fillStyle = ball.color;
ctx.fill();
});
}
});
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
function get_next_collision(balls,W,H)
{
var winner;
// ball-wall
balls.forEach( function(ball,i)
{
var t = [];
t['L'] = (ball.r - ball.x) / ball.vx; // s.x + t v.x = r
t['T'] = (ball.r - ball.y) / ball.vy;
t['R'] = (W-1-ball.r - ball.x) / ball.vx; // s.x + t v.x = (W-1)-r
t['B'] = (H-1-ball.r - ball.y) / ball.vy;
// get index of smallest positive t
var LR = t['L'] >= 0 ? 'L' : 'R',
TB = t['T'] >= 0 ? 'T' : 'B',
wall = t[LR] < t[TB] ? LR : TB;
if( ! winner || ( t[wall] <= winner.t ) )
winner = {
t : t[wall],
i : i,
wall: wall
};
});
return winner;
}
function collide_wall( A, wall )
{
if( wall == 'L' || wall == 'R' )
A.vx *= -1;
else
A.vy *= -1;
}
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/1.5.1/math.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<canvas id="myCanvas">
<!-- Insert fallback content here -->
</canvas>
Why is Firefox performing significantly worse than its competitors?
If I take the number of balls to 500 Chrome is still smooth, Firefox is seriously choppy.
If I take the number of balls down to 1 Firefox is still burring it.
Another experiment I did was applying a fixed velocity increment each frame, so that the smoothness of the animation accurately reflects the evenness of the render callback. This showed Firefox to be all over the place. Chrome on the other hand was smooth.
If there is sufficient interest, I can provide a snippet for that also and maybe tidy up the first one so that it offers a slider to modify the ball count.
As far as I can see, (1) Firefox definitely isn't giving us a genuine VSYNC callback, I suspect it is just using a timer, (2) even correcting for that by manually calculating elapsed time for each frame, it burrs the animation, maybe suggesting that it sometimes the callback fires in time to catch the VSYNC and sometimes it misses the boat, (3) there is an additional compositing hit that is disproportionate compared with Chrome.
Is there anything to be done about this?
EDIT: I found this question from four years ago! Poor performance of html5 canvas under firefox -- please don't mark this question as the duplicate unless it is certain that the answer to that question is still the only relevant answer four years later. I've deliberately included the version number in the question, as the question pertains specifically to the current version.

Ordering of transparent ParticleSystem with BufferGeometry in Threejs

Related to this question : Z-buffer issue with BufferGeometry in ParticleSystem
The given solution does not work for me, I made my own shader for rendering as I added custom attributes for size and UV. Everythinf works fine with the buffer geometry except the particle ordering for transparency.
If Activated > squared texture are partly hiding the other particles.
If Deactivated (depthTest : false) > particles looks fine but are not ordered.
Thanks for your answer, the subject has been raised several times but nothing worked for me yet.
Using Three.js 61
particleMaterial = new THREE.ShaderMaterial({
fragmentShader : document.getElementById("sectorPointFragment").textContent,
vertexShader : document.getElementById("sectorPointVertex").textContent,
uniforms : uniforms,
attributes : attributes,
transparent : true,
alphaTest : 0.5
});
_this.particles = new THREE.ParticleSystem(geometry, particleMaterial);
_this.particles.sortParticles = true;
So here is the solution I took, creating a new array with value each time. Seems to work, tested with 1000 particles not more
this.updateShaders = function() {
if(clock.getElapsedTime() - _lastZOrdering <= 0.2) {
return;
}
// z-ordering
var distances = [],
attributes = this.particles.geometry.attributes,
nbParticle = attributes.position.numItems / 3,
tmpPos = new THREE.Vector3(0, 0, 0);
for (var i = 0; i < nbParticle; ++i) {
tmpPos.set(
attributes.position.array[i * 3],
attributes.position.array[i * 3 + 1],
attributes.position.array[i * 3 + 2]
);
distances[i] = [this.controls.object.position.distanceTo(tmpPos), i];
}
distances.sort(function(a, b){
return b[0] - a[0];
});
var index, indexSrc, indexDst, tmpTab;
for (var val in attributes) {
tmpTab = new Float32Array(attributes[val].itemSize * nbParticle);
for(i = 0; i < nbParticle; ++i){
index = distances[i][1];
for(j = 0; j < attributes[val].itemSize; ++j){
indexSrc = index * attributes[val].itemSize + j;
indexDst = i * attributes[val].itemSize + j;
tmpTab[indexDst] = attributes[val].array[indexSrc];
}
}
attributes[val].array = tmpTab;
attributes[val].needsUpdate = true;
}
_lastZOrdering = clock.getElapsedTime();
}

Making falling objects come at random angles in AS3

I am making a missile defense type of game and am trying to get the missiles to fall at random angles. I also need the bullet image to turn at the angle I am shooting at. I am very unfamiliar with angles in AS3 so I need some help.
Code:
import spark.components.Image;
public var missiles:Array;
public var bullets:Array;
public var playerLife:Number;
public var targetX:Number;
public var targetY:Number;
public function init():void {
startGame();
}
public function onEnterFrame(e:Event):void {
if(Math.random() <.05 ){
//make a new missle
var newMissile:Image = new Image();
//draw to is
newMissile.source = "assets/missileDown.jpg";
//position it
newMissile.x = Math.random() * stage.stageWidth;
//animate it
newMissile.addEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//add it to missle array
missiles.push(newMissile);
//add it to the screen
gameGroup.addElement(newMissile);
}
}
public function startGame():void {
//makes new arrays
//gets rid of old arrays
missiles = new Array();
bullets = new Array();
//set player life
playerLife = 5;
//show player life
playerHealth.text = String(playerLife);
//add animation and mouse interation
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.CLICK, fireWeapon);
//set game over alpha
gameEnd.alpha = 0;
reset.alpha = 0;
//set game start alpha
playerHealth.alpha = 1;
healthLabel.alpha = 1;
}
//updates the missle
public function onMissileEnterFrame(e:Event):void {
//reference to target
var targetMissile:Image = Image(e.currentTarget);
//move missle down
targetMissile.y += 10;
//if missle has gone too far, remove it and player loses life
if(targetMissile.y > stage.stageHeight) {
playerLife --;
removeMissile(targetMissile);
//show player life
playerHealth.text = String(playerLife);
}
//if player is dead, game over
if(playerLife <= 0) {
gameOver();
}
}
//update bullet
public function onBulletEnterFrame(e:Event):void {
//get reference to bullet
var thisBullet:Bullet = Bullet(e.currentTarget);
//animate towards point..
//calculate difference between current position and desired position
var diffX:Number = thisBullet.targX - thisBullet.x;
var diffY:Number = thisBullet.targY - thisBullet.y;
//move 10% of difference closer
thisBullet.x += diffX * .1;
thisBullet.y += diffY * .1;
//chekc for overlap between bullet and missles
for(var i:Number = 0; i < missiles.length; i++) {
//if they do overlap, remove missle
if( thisBullet.hitTestObject(missiles[i]) ) {
removeMissile(missiles[i]);
removeBullet(thisBullet);
break;
}
}
//if we're 'close enough' to the target position, remove bullet
if(Math.abs(diffX) < 10 && Math.abs(diffY) < 10) {
removeBullet(thisBullet);
}
}
//gets rid of a missle
public function removeMissile(targetMissile:Image):void {
//removes the missle from the missiles array
for(var i:Number = missiles.length - 1; i >= 0; i--) {
if(missiles[i] == targetMissile) {
missiles.splice(i,1);
break;
}
}
//don't animate anymore
targetMissile.removeEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//remove from stage
gameGroup.removeElement(targetMissile);
}
//removes bullet from stage
public function removeBullet(targetBullet:Bullet):void {
//stop animation
targetBullet.removeEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//remove from stage
gameGroup.removeElement(targetBullet);
}
//shoot a bullet at the mouse position
public function fireWeapon(e:MouseEvent):void {
//make a new bullet
var newBullet:Bullet = new Bullet();
newBullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//position near the earth in the center
var halfStage:Number = stage.stageWidth / 2;
newBullet.x = halfStage;
newBullet.y = 500;
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
//add it to the stage
gameGroup.addElement(newBullet);
}
//you lose
public function gameOver():void {
//remove missles
for(var i:Number = 0; i < missiles.length; i++) {
removeMissile(missiles[i]);
}
//stop interaction
stage.removeEventListener(MouseEvent.CLICK, fireWeapon);
//stop animation
this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
//set game start alpha
playerHealth.alpha = 0;
healthLabel.alpha = 0;
//set game end alpha
gameEnd.alpha = 1;
reset.alpha = 1;
}
]]>
</fx:Script>
onEnterFrame
...
//position it
newMissile.x = Math.random() * stage.stageWidth;
//rotate it
newMissile.rotation = - (Math.random() * 60 - 30);
onMissileEnterFrame
...
//move missle down
//targetMissile.y += 10;
targetMissile.x -= 10 * Math.sin(targetMissile.rotation * Math.PI/180);
targetMissile.y += 10 * Math.cos(targetMissile.rotation * Math.PI/180);
fireWeapon
...
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
newBullet.rotation = - Math.atan((newBullet.x - newBullet.targX) / (newBullet.y - newBullet.targY)) * 180/Math.PI;

Random Image and get winner (Processing)

Hi I'm building a slot machine game and am having a few problems I'm pretty new with processing.
I've made this code and need the "wheels" to be random but they all have the same image (vertically)
I realise you won't be able to see the images so here's some links if you want them.
http://tinypic.com/r/i1jq7t/6 (diamond1)
http://tinypic.com/r/29fe5cg/6 (cherry1)
http://tinypic.com/r/sen1jo/6 (bell1)
int numFrames = 3; // The number of frames in the animation
int frame = 0;
int spincount = 0;
int state = 0;
PImage[] images1 = new PImage[3];
PImage[] images2 = new PImage[3];
PImage[] images3 = new PImage[3];
void setup() {
size(1080, 720);
frameRate(12);
// wheel 1
images1[0] = loadImage("bell1.png");
images1[1] = loadImage("cherry1.png");
images1[2] = loadImage("diamond1.png");
// wheel 3
images3[0] = loadImage("cherry1.png");
images3[1] = loadImage("bell1.png");
images3[2] = loadImage("diamond1.png");
// wheel 2
images2[0] = loadImage("diamond1.png");
images2[1] = loadImage("bell1.png");
images2[2] = loadImage("cherry1.png");
}
void draw() {
background(o);
//test state to see if I should be spinning
if(state == 1) {
spin();
}
}
//if a key is pressed then set the wheel to spin
void keyReleased() {
state = 1;
}
void spin() {
//spin for 5 times the break out
if (frame == 3) {
frame = 0;
spincount ++;
if (spincount == 10) {
state = 0;
spincount = 0;
//check if its a win and do stuff
winner();
}
}
// wheel 1
image(images1[frame], 20, 0);
image(images1[frame], 20, 170); //this is the image to test
image(images1[frame], 20, 340);
// wheel 2
image(images3[frame], 200, 0);
image(images3[frame], 200, 170); //this is the image to test
image(images3[frame], 200, 340);
// wheel 3
image(images2[frame], 400, 0);
image(images2[frame], 400, 170); //this is the image to test
image(images2[frame], 400, 340);
frame ++;
}
void winner() {
//are the names of the images the same
//if ((images3[frame].get(0,0)) == (images2[frame].get(0,0)) == (images1[frame].get(0,0))) {
// display a question from you list of questions by generating a random number and selecting the text
// wait for an answer
for (int i = 0; i < 400; i = i+1) {
if (keyPressed == true) {
// whats the key is it correct
}
if (i > 400) {
//display times up
}
}
}
// }
I'm also having issues with getting the "winner" (if the horizontal images's pixel in the left hand corner match go onto "winner".
I'd really appreciate any help anyone can offer.
There are a few problems with your code.
In the draw function, you are probably wanting to draw a black background, but you currently have the letter "o" instead of the number 0 (zero).
You probably want to draw the current wheel state to the screen in your draw function, right now you just have a black window unless you are spinning.
You can't compare colors directly.
Here is some modified code to get it working:
int numFrames = 3; // The number of frames in the animation
int maxSpin = 10;
int frame = 0;
int spincount = 0;
boolean spinning = false;
boolean checkWinner = false;
PImage[] images1 = new PImage[3];
PImage[] images2 = new PImage[3];
PImage[] images3 = new PImage[3];
void setup() {
size(1080, 720);
frameRate(12);
// wheel 1
images1[0] = loadImage("bell1.png");
images1[1] = loadImage("cherry1.png");
images1[2] = loadImage("diamond1.png");
// wheel 3
images3[0] = loadImage("cherry1.png");
images3[1] = loadImage("bell1.png");
images3[2] = loadImage("diamond1.png");
// wheel 2
images2[0] = loadImage("diamond1.png");
images2[1] = loadImage("bell1.png");
images2[2] = loadImage("cherry1.png");
}
void draw() {
background(0);
//test state to see if I should be spinning
// wheel 1
image(images1[frame], 20, 0);
image(images1[frame], 20, 170); //this is the image to test
image(images1[frame], 20, 340);
// wheel 2
image(images3[frame], 200, 0);
image(images3[frame], 200, 170); //this is the image to test
image(images3[frame], 200, 340);
// wheel 3
image(images2[frame], 400, 0);
image(images2[frame], 400, 170); //this is the image to test
image(images2[frame], 400, 340);
if (spinning) {
spin();
}
//this draws circles stroked in the color of the pixel at their center
//this is just to show how the code works, you can remove this
noFill(); // make the circles transparent
loadPixels(); // required before using pixels[]
color wheel1 = pixels[170*width+20];
color wheel2 = pixels[170*width+200];
color wheel3 = pixels[170*width+400];
stroke(wheel1);
ellipse(20, 170, 10, 10);
stroke(wheel2);
ellipse(200, 170, 10, 10);
stroke(wheel3);
ellipse(400, 170, 10, 10);
}
//if a key is pressed then set the wheel to spin
void keyReleased() {
if(!spinning) spinning = !spinning;
}
void spin() {
//spin for maxSpin times then break out
if (frame == numFrames-1) {
spincount ++;
if (spincount == maxSpin) {
spinning = !spinning;
spincount = 0;
//check if its a win and do stuff
winner();
}
else frame = 0;
}
else frame++;
}
void winner() {
loadPixels();
color wheel1 = pixels[171*width+21];
color wheel2 = pixels[171*width+201];
color wheel3 = pixels[171*width+401];
if(hue(wheel1) == hue(wheel2) && hue(wheel2) == hue(wheel3)) println("winner");
else println("not a winner");
}
This inclues your desired method of checking the corner colors on the images, but I would recommend just keeping track of which image is currently being displayed in the center.
I hope this at least gets you moving in the right direction.

Resources