Trying to figure out if I can fill in a closed path with color, can this be done?
Here's a basic example of what i'm having trouble with.
void setup() {
size(640, 360);
fill(122,161,158);
strokeWeight(1);
stroke(0,0,0);
line(548,144,516,220);
line(516,220,599,257);
line(599,257,548,144);
}
The fill doesn't seem to be working. Does fill only work on predefined shapes like rect()? If so is there a way to fill in closed lines.
I'm using processing 2.2.1
Please look into beginShape():
void setup() {
size(640, 360);
fill(122,161,158);
strokeWeight(1);
stroke(0,0,0);
beginShape();
vertex(548,144);vertex(516,220);
vertex(516,220);vertex(599,257);
vertex(599,257);vertex(548,144);
endShape();
}
Additionally check out createShape()
The line() function does just that: it draws a single line. Processing has no concept of areas defined using this function.
Instead, you want to use the shape functions. Here's one way you might do it:
void setup() {
size(640, 360);
fill(122,161,158);
strokeWeight(1);
stroke(0,0,0);
beginShape();
vertex(548,144);
vertex(516,220);
vertex(599);
vertex(30, 75);
endShape(CLOSE);
}
Related
In the p5 editor, I was trying to create a simple example that doesn't require a canvas, so I deleted the setup() and draw() functions. I realized that mousePressed() won't work without at least the setup() function being called. I can comment out createCanvas() and mousePressed() works just fine. Any ideas on why this is happening?
var luckyNum;
function mousePressed(){
luckyNum = int(random(0, 100));
createP("Your lucky number is " + luckyNum + "!");
}
The mousePressed() function works fine without draw(), but it does require setup().
Here's an example:
function setup() {
// empty
}
function mousePressed() {
background(random(255));
}
I'm not sure why this is. It's probably related to some internal initialization that only happens if p5.js detects a setup() function.
You might consider switching to pure JavaScript, since you don't seem to need many p5 features. You could attach a click listener to the <body> of your page and create a <p> element from there.
I'm just trying to get a basic box rendered with LibGDX (using Kotlin & LibKTX) but am running into some issues.
If I call the ModelBuilder createBox function without the specified begin() and end() functions my box is not rendered. I checked the materials, camera position, the bounding box, added a light source, etc. but it's just.. not there. I figured the issue was with the way I was building the nodes, as I can't find an issue with the Material.
This is how I am trying to render my box:
class HomeView(private val baseUI: BaseUI) : KtxScreen {
private val cam by lazy { PerspectiveCamera(67f, baseUI.aWidth, baseUI.aHeight) }
private val boxInstance: ModelInstance
private val modelBatch: ModelBatch
private val modelBuilder: ModelBuilder by lazy { ModelBuilder() }
private val vertexAttributes =
VertexAttributes.Usage.Position.toLong() or
VertexAttributes.Usage.Normal.toLong() or
VertexAttributes.Usage.TextureCoordinates.toLong()
private val greenMat by lazy { Material(ColorAttribute.createDiffuse(Color.GREEN)) }
private val environment by lazy { Environment() }
//------ end global
init {
cam.position.set(vec3(-10f, -10f, 10f))
cam.lookAt(0f, 0f, 0f)
cam.near = .1f
cam.far = 10f
cam.update()
modelBatch = ModelBatch()
modelBuilder.begin()
modelBuilder.createBox(5f, 5f, 5f, greenMat, vertexAttributes)
boxInstance = ModelInstance(modelBuilder.end())
environment.set(ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f))
environment.add(DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f))
}
override fun render(delta: Float) {
Gdx.gl.glViewport(0, 0, baseUI.aWidth.toInt(), baseUI.aHeight.toInt())
//this is working, screen appears grey
clearScreen(.3f, .3f, .3f, 1f)
modelBatch.begin(cam)
modelBatch.render(boxInstance, environment)
modelBatch.end()
}
//rest omitted
}
and here is my BaseUI class that I'm using to add the screen (I'm just trying to test screens out, this is all just for testing purposes so ignore the inefficiency please)
class BaseUI : KtxGame<KtxScreen>(), KtxApplicationAdapter {
val aWidth by lazy { Gdx.graphics.width.toFloat() }
val aHeight by lazy { Gdx.graphics.height.toFloat() }
override fun create() {
addScreen(HomeView(this))
setScreen<HomeView>()
}
override fun render() {
super<KtxGame>.render()
}
//rest ommitted
}
When I run this I get the following error:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Call end() first
which makes it seem like I need to call modelBatch.end() before I even create the nodes, which is confusing. I feel like I am doing something very basic wrong here, as I was able to get the basic 3D examples working back when I was trying this with Java a few years back.
So, two questions:
Why is LibGDX saying that I need to call end() before I create the nodes with ModelBuilder?
Is using modelBuilder.begin() and modelBuilder.end() actually the best way to use the ModelBuilder? I've yet to see a 3D example do this. Admittedly, all the 3D examples I have found have been from like 2013 so this might just be something that's been added. The LibGDX 3D section says to use this set of tutorials that do not use the begin() and end() functions, so I'm a bit confused as to what is the "best practice".
Thanks for any help!
edit: I tried it with a loaded model and it's having the same issue. Hmm..
edit2: Thank you Xoppa for helping me figure out what was wrong. The LibKTX specific function clearScreen() did not incorporate the GL20.GL_COLOR_BUFFER_BIT clear function as expected, which was my bad from reading their documentation. Adding this to my render function displayed the green box as expected:
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT)
LibGDX is not saying to call end() before you create a node, but that there is already an existing model that was created. Therefore, before creating another one you need to call end().
From your code sample, the reason why GdxRuntimeException is being thrown is that you call begin() and then createBox(). createBox() actually calls begin() in the function. (take a look here: https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g3d/utils/ModelBuilder.java) Therefore, the next begin() call the model is not null and the exception is thrown.
For best practices, if createBox() can satisfy your request than just use that. If you need something more complicated, such that createSphere(), createCapsule() don't work for you, then you need to call begin(), part(...), and end().
Hope this helps!
This might be a simple question but I can't figure it out.
I have a form called in my main function:
void Main() {
Mem = new MemoryManager();
Console::WriteLine("Thread Started");
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FinalSolution::ControlPanel form;
Thread^ cLoop = gcnew Thread(gcnew ThreadStart(loop));
cLoop->Start();
Application::Run(%form);
}
All I want to do is, if someone presses a key in general (not just when the program is in focus), it changes the background to a different color.
I have tried a few things but nothing has worked so far. Here is the loop and I have indicated where I want it to happen.
void loop() {
while (true) {
if (GetAsyncKeyState(key)) {
//Here
form.button->BackColor = System::Drawing::Color::ForestGreen;
}
}
}
Of course the issue is that this function doesn't know what form is, but I don't know how to tell it.
Ended up just putting the loop directly in the form header and that solved the problem.
I want to get the time between successive mouse clicks in ms. This is what I have tried:
void setup(){
size(512,512);
background(100,100,0);
}
void draw(){
}
void mousePressed(){
println(new Date() - oldtime);
var oldtime=new Date();
}
The problem appears to be that processing.js does not remember the value of oldtime between calls to mousePressed().
On the first call, there has been no previous mouse click, oldtime is undefined, and the time should be NaN. But after the first click, oldtime is set, and so the above should work. I tried doing
var oldtime=new Date();
outside mousePressed() so that the first call would not be NaN, but no luck.
Thanks very much for any help.
===========================
The problem had to do with variable "scope". This works now
var oldtime=new Date();
void setup(){
size(512,512);
background(100,100,0);
}
void draw(){
}
void mousePressed(){
println(new Date() - oldtime);
oldtime=new Date();
}
There is a built in method/function for this called millis(), no need to use the Date class. There is also no reason to call var. I would also initialize your classes and variables in the setup method. Here is how these changes would look in your code in processing syntax:
int oldtime;
void setup(){
size(512,512);
background(100,100,0);
oldtime = millis()
}
void draw(){
}
void mousePressed(){
println(millis() - oldtime);
oldtime = millis()
}
If you are familiar with JavaScript you might find it beneficial use processing directly in javascript. That way it is easy to mix and match what you need and to use standard javascript debugging tools. There is a great tutorial on how to do this here:
http://processingjs.org/articles/jsQuickStart.html#javascriptonlyprocessingcode
In my title screen, i have a code saying that the first controller using A is the PlayerIndex.one.
Here is the code:
public override void HandleInput(InputState input)
{
for (int anyPlayer = 0; anyPlayer <4; anyPlayer++)
{
if (GamePad.GetState((PlayerIndex)anyPlayer).Buttons.A == ButtonState.Pressed)
{
FirstPlayer = (PlayerIndex)anyPlayer;
this.ExitScreen();
AddScreen(new Background());
}
}
}
My question is: How can i use the "FirstPlayer" in other classes? (without this, there is no interest in this code)
I tried the Get Set thing but i can't make it work. Does i need to put my code in another class? Do you use other code to make this?
Thanks.
You can make a static variable say : SelectedPlayer,
and assign first player to it!
then you can call the first player through this class,
for example
class GameManager
{
public static PlayerIndex SelectedPlayer{get;set;}
..
..
..
}
and right after the loop in your code, you can say:
GameManager.SelectedPlayer = FirstPlayer;
I hope this helps, if your code cold be clearer that would be easier to help :)
Ok, so to do this properly you're going to have to redesign a little.
First off, you should be checking for a new gamepad input (i.e. you should be exiting the screen only when 'A' has been newly pressed). To do this you should be storing previous and current gamepad states:
private GamePadState currentGamePadState;
private GamePadState lastGamePadState;
// in your constructor
currentGamePadState = new GamePadState();
lastGamePadState = new GamePadState();
// in your update
lastGamePadState = currentGamePadState;
currentGamePadState = GamePad.GetState(PlayerIndex.One);
Really what you need to do is modify your class that deals with input. The basic functionality from your HandleInput function should be moved into your input class. Input should have a collection of functions that test for new/current input. For example, for the case you posted:
public Bool IsNewButtonPress(Buttons buton)
{
return (currentGamePadState.IsButtonDown(button) && lastGamePadState.IsButtonUp(button));
}
Then you can write:
public override void HandleInput(InputState input)
{
if (input.IsNewButtonPress(Buttons.A)
{
this.ExitScreen();
AddScreen(new Background());
}
}
Note: this will only work for one controller. To extend the implementation, you'll need to do something like this:
private GamePadState[] currentGamePadStates;
private GamePadState[] lastGamePadStates;
// in your constructor
currentGamePadStates = new GamePadState[4];
currentGamePadStates[0] = new GamePadState(PlayerIndex.One);
currentGamePadStates[1] = new GamePadController(PlayerIndex.Two);
// etc.
lastGamePadStates[0] = new GamePadState(PlayerIndex.One);
// etc.
// in your update
foreach (GamePadState s in currentGamePadStates)
{
// update all of this as before...
}
// etc.
Now, you want to test every controller for input, so you'll need to generalise by writing a function that returns a Bool after checking each GamePadState in the arrays for a button press.
Check out the MSDN Game State Management Sample for a well developed implementation. I can't remember if it supports multiple controllers, but the structure is clear and can easily be adapted if not.