Structuring Views in Korge - korge

I'm not sure if this is the best place to ask this question or not but I feel like I'm struggling to grasp something relatively simple and can't find any decent advice on it in relation to KorGE so if anyone can offer any assistance it would be much appreciated.
This is a a question that can relate to multiple things so I'll use a simple example to demonstrate.
Say I set up a solidRect and I want it to travel along the x coordinate by one on each update I might do something like this:
solidRect(16.0, 16.0, Colors.GREEN) {
x = 0.0;
y = 0.0;
addUpdater {
x += 1.0;
}
}
This will create a solid rectangle in the container of 16px by 16px at the position 0,0 and each update will then add 1 to the x position moving it across the screen. Now what I'd like to do is encapsulate this logic into a class in a separate file so I could do something along the lines of the following:
movingShape() {
x = 0.0,
y = 0.0,
}
My expectation being that this would create the same solid rect visible in the scene, position it a 0, 0 and then the updater would be contained within the class itself, so I can use this logic multiple times. However, whenever I do this either init the solidRect in the class or passing it through in the constructor the updater function fails to fire.
As a longer fully functioning example I'd want something along the lines of this:
suspend fun main() = Korge(width = 512.0, height=512.0, bgcolor = Colors["#2b2b2b"]) {
val sceneContainer = sceneContainer();
sceneContainer.changeTo({MyScene()});
}
class MyScene : Scene() {
override suspend fun SContainer.sceneMain() {
movingShape() {
x = 0.0;
y = 0.0;
}
}
}
How would I implement the movingShape class in this example so it works kind of how I mentioned above?
Once again, sorry, if this seems like a trivial question or could be easily answered through some Kotlin. I'm relatively new to the language mainly coming from a Java / JS / PHP background. Any help would be appreciated here? I've tried to look for a good example of this but so far have turned up empty.

Related

adding perlin noise to THREE.js r121

I have been struggling with finding a good tutorial to add perlin noise to a newer version of THREE.js. I have found many tutorials and examples but they all seem to break when I add r121 into the mix.
I've tried a great example from Codepen using a script from jeromeetienne.github.io
I've also tried this guys tutorial and file http://www.stephanbaker.com/post/perlinterrain/
I've tried several others and no luck. I am convinced it's due to THREE versions being used. Most of what I can find use an old version of THREE.js. I have forked what others have, and it works with the old version they are using but not the new one.
//land
let landGeo = new THREE.PlaneGeometry(500,500, 50, 50);
let landMat = new THREE.MeshStandardMaterial({
color:'green'
})
land = new THREE.Mesh(landGeo, landMat);
scene.add(land);
noise.seed(Math.random());
for(let i=1;i<100;i++) {
for(let j=1;j<100;j++) {
var value = noise.simplex2(i / 100, j / 100);
// ... or noise.simplex3 and noise.perlin3:
// var value = noise.simplex3(i / 100, j / 100, clock);
landGeo[i][j].r = Math.abs(value) * 256;
}
}
So does anyone know how can get some version of perlin noise working? I am trying to creat terrain.
https://codepen.io/jfirestorm44/pen/mdEEwqb?editors=0010
Thank you
Did you check the browser console errors? It should be the first thing you check.
I see the error Cannot read property '1' of undefined.
Which tells me that something is wrong with the line landGeo[i][j].r = Math.abs(value) * 256;
The vertices are in a single dimension array and are vector objects. I am pretty sure it should be:
landGeo.vertices[i+j].z = Math.abs(value) * 256;.
Also, I am not sure you are calling the noise function with the correct parameters, though I could be wrong and you may be wanting it like it is.
var value = noise.simplex2(i / 100, j / 100);
Also, you are starting your for loops at 1, for(let i=1;i<100;i++) {, I am pretty sure you want to start them at 0. for(let i=0;i<100;i++) {
There is always the option of doing the displacement in a shader like this 3d example, only in 2d

Best practice on instantiating different types of the same es6 class

I am building an HTML5 Canvas 2d game and i have some es6 classes on my project. One of them is Obstacles. What i want to do is having the ability to create a different instance of this class depending on a given type (eg. small, thick, tall etc).
What is the best way to do this?
Just add another parameter to the constructor of the class and name it type?
Or just create subclasses of the main class Obstacle by extending it (eg. SmallObstacle, TallObstacle) given a random type value?
Thanks in advance.
Your question is based around how you want to build and implement your data structures. Neither option is necessarily better than the other 100% of the time. I'll explain the pro's and con's of each below along with my personal solution. You can decide which one is more feasible for you to implement.
Option 1:
Pros:
Easy to insert into the class and deal with later in your code
Leaves your class neat and slimmer
Cons:
You have to deal with it later in your code. When initializing (maybe even when updating/rendering) your code needs to interpret what the types are and build each obstacle based on that.
Option 2:
Pros:
Makes an organized class
Not much work later in your code since you're just pulling preset specifications rather than interpreting them
Cons:
The class is much larger
You are likely to be repeating some code (although if you do it well, you won't)
My Opinion:
Personally I would skip specifying "large," "medium," "tall," "wide." Instead, I would use some logic when implementing the class and make the height and width whatever I want. You could take advantage of how one can easily specify a value while also providing a default with a function constructor.
Here is a snippet example:
class obstacle {
constructor(x, y, w=150, h=150) {
this.x = x;
this.y = y;
this.width = w; //default is 150
this.height = h; //so it's medium or something
this.sprite = ...; //etc.
}
}
// Initialize 100 obstacles :P
for (let i=0; i<100; i++) {
let x = Math.random() * scene.width;
let y = Math.random() * scene.height;
let foo = new obstacle(x, y);
/* When you want different width and height instead
of the default, construct like this:
let bar = new obstacle(x, y, width, height);
*/
}

SKEmitterNode not showing particle

I wonder what's wrong with my code, it doesnt show the particles correctly.
and here's the expected particle
implementation
physicsWorld.contactDelegate = self
self.scene?.backgroundColor = UIColor.blackColor()
self.scene?.size = CGSize(width: 640, height: 1136)
self.addChild(SKEmitterNode(fileNamed: "MagicParticle")!)
You should try to safely unwrap the particle file first, just to make sure it cannot be nil
if let particle = SKEmitterNode(fileNamed: "MagicParticle") {
particle.position = ...
addChild(particle)
}
Its strange thats its not working, looking at your pictures it seems like you do not have a typo.
Did you change the default spark.png in the particle effect?
Try cleaning your project or maybe delete the effect and create it again if it still doesn't work
As a side note, you can delete the 2 words
scene?...
You are already in a SKScene, so self is the scene and therefore you can just say
self.backgroundColor = ...
self.size = ...
or better
backgroundColor = ...
size = ...
As a general good coding practice in swift try to only use "self" when the compiler forces you too. So say
addChild(...)
instead of
self.addChild(...)
I think you should include also the file's extension, like this.
self.addChild(SKEmitterNode(fileNamed: "MagicParticle.sks")!)

libGDX- Exact collision detection - Polygon creation?

I've got a question about libGDX collision detection. Because it's a rather specific question I have not found any good solution on the internet yet.
So, I already created "humans" that consist of different body parts, each with rectangle-shaped collision detection.
Now I want to implement weapons and skills, which for example look like this:
Skill example image
Problem
Working with rectangles in collision detections would be really frustrating for players when there are skills like this: They would dodge a skill successfully but the collision detector would still damage them.
Approach 1:
Before I started working with Libgdx I have created an Android game with a custom engine and similar skills. There I solved the problem following way:
Detect rectangle collision
Calculate overlapping rectangle section
Check every single pixel of the overlapping part of the skill for transparency
If there is any non-transparent pixel found -> Collision
That's a kind of heavy way, but as only overlapping pixels are checked and the rest of the game is really light, it works completely fine.
At the moment my skill images are loaded as "TextureRegion", where it is not possible to access single pixels.
I have found out that libGDX has a Pixmap class, which would allow such pixel checks. Problem is: having them loaded as Pixmaps additionally would 1. be even more heavy and 2. defeat the whole purpose of the Texture system.
An alternative could be to load all skills as Pixmap only. What do you think: Would this be a good way? Is it possible to draw many Pixmaps on the screen without any issues and lag?
Approach 2:
An other way would be to create Polygons with the shape of the skills and use them for the collision detection.
a)
But how would I define a Polygon shape for every single skill (there are over 150 of them)? Well after browsing a while, I found this useful tool: http://www.aurelienribon.com/blog/projects/physics-body-editor/
it allows to create Polygon shapes by hand and then save them as JSON files, readable by the libGDX application. Now here come the difficulties:
The Physics Body Editor is connected to Box2d (which I am not using). I would either have to add the whole Box2d physics engine (which I do not need at all) just because of one tiny collision detection OR I would have to write a custom BodyEditorLoader which would be a tough, complicated and time-intensive task
Some images of the same skill sprite have a big difference in their shapes (like the second skill sprite example). When working with the BodyEditor tool, I would have to not only define the shape of every single skill, but I would have to define the shape of several images (up to 12) of every single skill. That would be extremely time-intensive and a huge mess when implementing these dozens of polygon shapes
b)
If there is any smooth way to automatically generate Polygons out of images, that could be the solution. I could simply connect every sprite section to a generated polygon and check for collisions that way. There are a few problems though:
Is there any smooth tool which can generate Polygon shapes out of an image (and does not need too much time therefor)?
I don't think that a tool like this (if one exists) can directly work with Textures. It would probably need Pixmaps. It would not be needed to keep te Pixmaps loaded after the Polygon creation though. Still an extremely heavy task!
My current thoughts
I'm stuck at this point because there are several possible approaches but all of them have their difficulties. Before I choose one path and continue coding, it would be great if you could leave some of your ideas and knowledge.
There might be helpful classes and code included in libGDX that solve my problems within seconds - as I am really new at libGDX I just don't know a lot about it yet.
Currently I think I would go with approach 1: Work with pixel detection. That way I made exact collision detections possible in my previous Android game.
What do you think?
Greetings
Felix
I, personally, would feel like pixel-to-pixel collision would be overkill on performance and provide some instances where I would still feel cheated - (I got hit by the handle of the axe?)
If it were me, I would add a "Hitbox" to each skill. StreetFighter is a popular game which uses this technique. (newer versions are in 3D, but hitbox collision is still 2D) Hitboxes can change frame-by-frame along with the animation.
Empty spot here to add example images - google "Streetfighter hitbox" in the meantime
For your axe, there could be a defined rectangle hitbox along the edge of one or both ends - or even over the entire metal head of the axe.
This keeps it fairly simple, without having to mess with exact polygons, but also isn't overly performance heavy like having every single pixel being its own hitbox.
I've used that exact body editor you referenced and it has the ability to generate polygons and/or circles for you. I also made a loader for the generated JSON with the Jackson library. This may not be the answer for you since you'd have to implement box2d. But here's how how I did it anyway.
/**
* Adds all the fixtures defined in jsonPath with the name'lookupName', and
* attach them to the 'body' with the properties defined in 'fixtureDef'.
* Then converts to the proper scale with 'width'.
*
* #param body the body to attach fixtures to
* #param fixtureDef the fixture's properties
* #param jsonPath the path to the collision shapes definition file
* #param lookupName the name to find in jsonPath json file
* #param width the width of the sprite, used to scale fixtures and find origin.
* #param height the height of the sprite, used to find origin.
*/
public void addFixtures(Body body, FixtureDef fixtureDef, String jsonPath, String lookupName, float width, float height) {
JsonNode collisionShapes = null;
try {
collisionShapes = json.readTree(Gdx.files.internal(jsonPath).readString());
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (JsonNode node : collisionShapes.findPath("rigidBodies")) {
if (node.path("name").asText().equals(lookupName)) {
Array<PolygonShape> polyShapes = new Array<PolygonShape>();
Array<CircleShape> circleShapes = new Array<CircleShape>();
for (JsonNode polygon : node.findPath("polygons")) {
Array<Vector2> vertices = new Array<Vector2>(Vector2.class);
for (JsonNode vector : polygon) {
vertices.add(new Vector2(
(float)vector.path("x").asDouble() * width,
(float)vector.path("y").asDouble() * width)
.sub(width/2, height/2));
}
polyShapes.add(new PolygonShape());
polyShapes.peek().set(vertices.toArray());
}
for (final JsonNode circle : node.findPath("circles")) {
circleShapes.add(new CircleShape());
circleShapes.peek().setPosition(new Vector2(
(float)circle.path("cx").asDouble() * width,
(float)circle.path("cy").asDouble() * width)
.sub(width/2, height/2));
circleShapes.peek().setRadius((float)circle.path("r").asDouble() * width);
}
for (PolygonShape shape : polyShapes) {
Vector2 vectors[] = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
vectors[i] = new Vector2();
shape.getVertex(i, vectors[i]);
}
shape.set(vectors);
fixtureDef.shape = shape;
body.createFixture(fixtureDef);
}
for (CircleShape shape : circleShapes) {
fixtureDef.shape = shape;
body.createFixture(fixtureDef);
}
}
}
}
And I would call it like this:
physics.addFixtures(body, fixtureDef, "ship/collision_shapes.json", shipType, width, height);
Then for collision detection:
public ContactListener shipsExplode() {
ContactListener listener = new ContactListener() {
#Override
public void beginContact(Contact contact) {
Body bodyA = contact.getFixtureA().getBody();
Body bodyB = contact.getFixtureB().getBody();
for (Ship ship : ships) {
if (ship.body == bodyA) {
ship.setExplode();
}
if (ship.body == bodyB) {
ship.setExplode();
}
}
}
};
return listener;
}
then you would add the listener to the world:
world.setContactListener(physics.shipsExplode());
my sprites' width and height were small since you're dealing in meters not pixels once you start using box2d. One sprite height was 0.8f and width was 1.2f for example. If you made the sprites width and height in pixels the physics engine hits speed limits that are built in http://www.iforce2d.net/b2dtut/gotchas
Don't know if this still matter to you guys, but I built a small python script that returns the pixels positions of the points in the edges of the image. There is room to improve the script, but for me, for now its ok...
from PIL import Image, ImageFilter
filename = "dship1"
image = Image.open(filename + ".png")
image = image.filter(ImageFilter.FIND_EDGES)
image.save(filename + "_edge.png")
cols = image.width
rows = image.height
points = []
w = 1
h = 1
i = 0
for pixel in list(image.getdata()):
if pixel[3] > 0:
points.append((w, h))
if i == cols:
w = 0
i = 0
h += 1
w += 1
i += 1
with open(filename + "_points.txt", "wb") as nf:
nf.write(',\n'.join('%s, %s' % x for x in points))
In case of updates you can find them here: export positions

Moving MovieClip Effects

I have a movieclip.
Its current y is 0, and I want to move it to y 100.
How I'm currently doing it is
onenterframe { Y += 2 }
How would I do it that it starts off slow and ends slow but speeds up in the middle?
There are lots of ways to do this, one way is to use the Tween class that is provided by Adobe (actionscript 2 + 3)
import fl.transitions.Tween;
import fl.transitions.easing.*;
var tween:Tween;
function moveTo(targetY:Number, numberOfFrames:int) {
tween = new Tween(this, "y", Regular.easeInOut, y, targetY, numberOfFrames);
}
See the flash reference for more info
You can also use just the Regular.easeInOut function in your own onEnterFrame loop, or choose to use one of many community written tween libraries like gTween or TweenLite.

Resources