I want to create a typing game, so my sprites need to be generated in run time, with "labels". a String become a sprite to be typed. Anyone knows how to do this?
You can insert a Q.UI.Text object into a sprite like this:
var Q = Quintus()
.include('Sprites, Scenes, UI')
.setup({ maximize: true })
Q.Sprite.extend('LabelSprite', {
init: function(p) {
this._super(p, {text: 'default text'});
}
});
Q.scene("level1",function(stage) {
var label_sprite = stage.insert(new Q.LabelSprite({
x: 150,
y: 50,
label_text: 'label-text in a sprite',
label_text_color: 'grey',
label_offset_x: 0,
label_offset_y: 0
}));
var label = stage.insert(new Q.UI.Text({
label: label_sprite.p.label_text,
color: label_sprite.p.label_text_color,
x: label_sprite.p.label_offset_x,
y: label_sprite.p.label_offset_y
}), label_sprite);
});
Q.stageScene("level1");
Here is the above code in jsfiddle to demonstrate.
Also, the Scenes page of the Quintus documentation has a section called "Inserting objects into a stage", which is somewhat related to the concept.
Hope that helps!
Related
The game I'm creating doesn't require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: "pointer"});, sprite.on('pointermove', function(activePointer) {...}); and similar. However I noticed two issues with that:
The sprite has some area which are transparent. The interactive functions will still trigger when clicking on those transparent areas, which is unideal.
When playing a sprite animation, the interactive area doesn't seem to entirely (at all?) change, thus if the sprite ends on a frame bigger than the previous, there end up being small areas I can't interact with.
One option I thought of was to create a polygon over my sprite, which covers the area I want to be interactive. However before I do that, I simply wanted to ask if there are simpler ways to fix these issues.
Was trying to find an answer for this myself just now..
Think Make Pixel Perfect is what you're looking for.
this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
https://newdocs.phaser.io/docs/3.54.0/focus/Phaser.Input.InputPlugin-makePixelPerfect
This might not be the best solution, but I would solve this problem like this. (If I don't want to use physics, and if it doesn't impact the performance too much)
I would check in the event-handler, if at the mouse-position the pixel is transparent or so, this is more exact and less work, than using bounding-boxes.
You would have to do some minor calculations, but it should work well.
btw.: if the origin is not 0, you would would have to compensate in the calculations for this. (in this example, the origin offset is implemented)
Here is a demo, for the click event:
let Scene = {
preload ()
{
this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
},
create ()
{
// Animation set
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
frameRate: 8,
repeat: -1
});
// create sprite
const cody = this.add.sprite(200, 100).setOrigin(0);
cody.play('walk');
cody.setInteractive();
// just info text
this.mytext = this.add.text(10, 10, 'Click the Sprite, or close to it ...', { fontFamily: 'Arial' });
// event to watch
cody.on('pointerdown', function (pointer) {
// calculate x,y position of the sprite to check
let x = (pointer.x - cody.x) / (cody.displayWidth / cody.width)
let y = (pointer.y - cody.y) / (cody.displayHeight / cody.height);
// just checking if the properties are set
if(cody.anims && cody.anims.currentFrame){
let currentFrame = cody.anims.currentFrame;
let pixelColor = this.textures.getPixel(x, y, currentFrame.textureKey, currentFrame.textureFrame);
// alpha > 0 a visible pixel of the sprite, is clicked
if(pixelColor.a > 0) {
this.mytext.text = 'Hit';
} else {
this.mytext.text = 'No Hit';
}
// just reset the textmessage
setTimeout(_ => this.mytext.text = 'Click the Sprite, or close to it ...' , 1000);
}
}, this);
}
};
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: Scene
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
I have a scenario like I have a Bootstrap slider, in that I want track points on the track of the slider and the tool tip must be fixed (i.e. it must be exist even after click).
Here is my Plunker link:
http://embed.plnkr.co/D3GJQn/preview
I need to get points on the track as shown in below image:
Add property tooltip:"always" to show the tooltip always
$(document).ready(function () {
var mySlider = $("#slider-input").slider({
min:0,
max: 4200,
value:1000,
step:1000,
tooltip:"always"
});
});
You can see the complete set of options here - https://github.com/seiyria/bootstrap-slider#options
To get the current value of slide, see below.
$("#slider-input").on('slide', function (ev) {
console.log($("#slider-input").val());
});
You can use ticks: [0, 500, 1000, 1500], property to show intermedaite points. for more http://seiyria.com/bootstrap-slider/
example - https://plnkr.co/edit/W8c2UuPMiEeMwQ8g7kCV?p=preview
This is how I got the current value:
$(document).ready(function () {
var mySlider = $("#slider-input").slider({
min:0,
max: 4200,
value:1000,
step:1000,
formatter: function(value) {
return 'Current value: ' + value;
}
});
});
You can also show the value by doing:
$("#mySlider").on("slide", function(slideEvt) {
$("#sliderValue").text(slideEvt.value);
});
with HTML:
<span>Current Value: <span id="sliderValue">1</span></span>
Here is a link to show some examples I found after doing this:
http://seiyria.com/bootstrap-slider/
Hope this helps!
Take a look at Example 13. Here is the example code, take note of the ticks property:
var slider = new Slider("#ex13", {
ticks: [0, 100, 200, 300, 400],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_snap_bounds: 30
});
I'm searching for a way in JavaScript how I can detect if an object like this:
var box = {
x: 5,
y: 19,
width: 10,
height: 5,
draw: function(ctx){...draw Box on context "ctx"},
touchingColor: function(ctx,color){...}
}
So basically what I'm looking for is a function touchingColor, that returns true if my box is touching the specified color in the specified context.
Is there a way to accomplish that, or do I need to keep track of the things I drawed on the canvas?
Well, I found a way to solve this issue :) Hopefully it helps someone...
var box = {
x: 5,
y: 19,
width: 10,
height: 5,
draw: function(ctx){...draw Box on context "ctx"},
touchingColor: function(ctx,r,g,b){
var data = ctx.getImageData(this.x,this.y,this.width,this.height);
for(var i=0;i<data.length;i+=4){
if(
data[i+0]==r&&
data[i+1]==g&&
data[i+2]==b
){
return true;
}
}
return false;
}
};
I have some text, that has a class in the form of "link variabletext" (where variabletext is unique to each link). I'm trying to set this up so that when I mouseover the text, the corresponding object changes color, using jQuery.
A jsFiddle of what I have: http://jsfiddle.net/hdJCn/
The code I'm using:
One
Two
Three
<div id="container"></div>
var stage = new Kinetic.Stage({
container: 'container'
});
var layer = new Kinetic.Layer();
var onecircle = new Kinetic.Ellipse({
x: 100,
y: 100,
radius: {
x: 50,
y: 50
},
strokeWidth: 1,
stroke: 'black'
});
layer.add(onecircle);
stage.add(layer);
$('.link').mouseover(function () {
var numclass = $(this).attr('class').split(' ')[1];
(numclass + 'circle').setStroke('orange');
});
The problem is that it says that the object has no method "setStroke". If I take that same object name and hardcode it (so onecircle.setStroke instead of the above) it works fine. I'm not sure why this is and so far am at a loss.
Figured it out. I had to convert the string to an object:
var obj = eval(numclass+'circle');
And then use obj.setStroke....
With Kinetic, is it possible to set a mouseover on a text? The code below does not work. If a replace the Text by a Rectangle, it works fine.
...
var layer = new Kinetic.Layer();
var test = new Kinetic.Text({
x: 20,
y: 20,
text: "test",
textFill:"black"
});
test.on("mouseover", function(){
alert("mouseover");
});
layer.add(test);
Thank you for your help!
UPDATE:
Ok, I searched a little bit more and it seems that it is necessary to use pixel detection.
see this tutorial fore more details
The result is not perfect for the moment but it is better than nothing.
I have trouble dealing with a similar text behaviour and after diving in repository history I found that now Text has detectionType setted to 'pixel' by default.
Try to change your Text declaration like following :
var test = new Kinetic.Text({
x: 20,
y: 20,
text: "test",
textFill: 'black',
detectionType: 'path',
draggable: true
});