diff --git a/frice/src/main/kotlin/org/frice/Game.kt b/frice/src/main/kotlin/org/frice/Game.kt index df81005..bd2aa06 100644 --- a/frice/src/main/kotlin/org/frice/Game.kt +++ b/frice/src/main/kotlin/org/frice/Game.kt @@ -2,18 +2,31 @@ package org.frice +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.graphics.Canvas +import android.net.* +import android.os.Bundle +import android.os.PersistableBundle import android.support.v7.app.AppCompatActivity +import android.view.View import org.frice.event.* import org.frice.obj.button.FText -import org.frice.platform.* +import org.frice.platform.FriceGame +import org.frice.platform.Layer import org.frice.platform.adapter.DroidDrawer import org.frice.platform.adapter.DroidImage import org.frice.resource.graphics.ColorResource -import org.frice.utils.cast -import org.frice.utils.message.* +import org.frice.utils.data.readString +import org.frice.utils.data.save +import org.frice.utils.message.FLog import org.frice.utils.shape.FRectangle import org.frice.utils.time.* -import java.util.function.Consumer +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread +import java.net.URL + /** * The base game class using Swing as renderer. @@ -29,6 +42,12 @@ import java.util.function.Consumer */ @Suppress("LeakingThis") open class Game @JvmOverloads constructor(layerCount: Int = 1) : AppCompatActivity(), FriceGame { + private var screenWidth: Int = -1 + private var screenHeight: Int = -1 + + override fun getHeight() = screenHeight + override fun getWidth() = screenWidth + override val layers = Array(layerCount) { Layer() } override var paused = false set(value) { @@ -42,14 +61,41 @@ open class Game @JvmOverloads constructor(layerCount: Int = 1) : AppCompatActivi field = value } + override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) { + super.onCreate(savedInstanceState, persistentState) + setContentView(canvas) + screenWidth = resources.displayMetrics.widthPixels + screenHeight = resources.displayMetrics.heightPixels + FLog.v("height: $screenHeight, width: $screenWidth") + } + + override fun onDestroy() { + onExit() + super.onDestroy() + } + + override fun onPause() { + super.onPause() + loseFocus = true + FClock.pause() + onLoseFocus() + } + + override fun onResume() { + super.onResume() + loseFocus = false + FClock.resume() + onFocus() + } + override fun dialogConfirmYesNo(msg: String, title: String) = - JOptionPane.showConfirmDialog(this, msg, title, YES_NO_OPTION) == YES_OPTION + TODO() // JOptionPane.showConfirmDialog(this, msg, title, YES_NO_OPTION) == YES_OPTION override fun dialogShow(msg: String, title: String) = - JOptionPane.showMessageDialog(this, msg, title, OK_OPTION) + TODO() // JOptionPane.showMessageDialog(this, msg, title, OK_OPTION) override fun dialogInput(msg: String, title: String): String = - JOptionPane.showInputDialog(this, msg, title) + TODO() // JOptionPane.showInputDialog(this, msg, title) override var debug = true override var autoGC = true @@ -59,18 +105,6 @@ open class Game @JvmOverloads constructor(layerCount: Int = 1) : AppCompatActivi override var loseFocusChangeColor = true - override var isFullScreen: Boolean - get() = false - set(value) { - throw UnsupportedOperationException() - } - - override var isAlwaysTop: Boolean - get() = false - set(value) { - throw UnsupportedOperationException() - } - @get:JvmName(" refresh") internal val refresh = FTimer(4) override var millisToRefresh: Int @@ -79,152 +113,104 @@ open class Game @JvmOverloads constructor(layerCount: Int = 1) : AppCompatActivi refresh.time = value } - internal val panel: SwingGamePanel = SwingGamePanel() - - override val drawer: DroidDrawer + private val canvas = FriceCanvas() + var drawer: DroidDrawer? = null val fpsCounter = FpsCounter() init { - isResizable = false onInit() - drawer = DroidDrawer(this).apply(JvmDrawer::init) - isVisible = true - FLog.v("If the window doesn't appear, please call `launch(YourGameClass.class)` instead of the constructor.") } open fun onExit() { - if (dialogConfirmYesNo("Are you sure to exit?")) { - dispose() - System.exit(0) - } + TODO() } override fun measureText(text: FText): FRectangle { - drawer.useFont(text) - val g = drawer.g - val font = text.fonttmpobj as? Font ?: g.font - return FRectangle(font.getStringBounds(text.text, g.fontRenderContext)) + TODO() } override fun measureTextWidth(text: FText): Int { - drawer.useFont(text) - val g = drawer.g - val font = text.fonttmpobj as? Font ?: g.font - return g.getFontMetrics(font).stringWidth(text.text) + TODO() } - /** - * add keyboard listeners with lambda - */ - fun addKeyListener( - typed: Consumer? = null, - pressed: Consumer? = null, - released: Consumer? = null) { - addKeyListener(object : KeyListener { - override fun keyPressed(e: KeyEvent) { - pressed?.accept(e) - } + fun Game.openWeb(url: String) = startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) - override fun keyReleased(e: KeyEvent) { - released?.accept(e) - } - - override fun keyTyped(e: KeyEvent) { - typed?.accept(e) - } - }) - } - - override val screenCut get() = drawer.friceImage - - fun addKeyTypedEvent(keyCode: Int, key: Consumer) - = addKeyListener(typed = Consumer { e -> if (e.keyCode == keyCode) key.accept(e) }) + private val Game.connection: NetworkInfo? + get() = (getSystemService(Context.CONNECTIVITY_SERVICE) + as ConnectivityManager).activeNetworkInfo - fun addKeyPressedEvent(keyCode: Int, key: Consumer) - = addKeyListener(pressed = Consumer { e -> if (e.keyCode == keyCode) key.accept(e) }) - fun addKeyReleasedEvent(keyCode: Int, key: Consumer) - = addKeyListener(released = Consumer { e -> if (e.keyCode == keyCode) key.accept(e) }) - - override fun setCursor(o: FriceImage) { - cursor = toolkit.createCustomCursor(cast(o).image, Point(0, 0), "cursor") - } + /** + * if this value is null, + * it means I have 2 load data from Sp. + */ + val isNetConnected: Boolean + get() = connection != null && connection!!.isConnected /** - * all rendering work and game object calculating are here. + * this will cache the data into SharedPreference + * next time when the network is invalid, it will return the data + * stored in the SharedPreference. * - * Created by ice1000 on 2016/8/13. - * @author ice1000 - * @since v0.1 + * this method extended String. */ - inner class SwingGamePanel : JComponent() { - - init { - addMouseListener(object : MouseListener { - override fun mouseClicked(e: MouseEvent) { - mouse(swingMouse(e, MOUSE_CLICKED)) - onMouse(swingMouse(e, MOUSE_CLICKED)) - } - - override fun mouseEntered(e: MouseEvent) = onMouse(swingMouse(e, MOUSE_ENTERED)) - override fun mouseExited(e: MouseEvent) = onMouse(swingMouse(e, MOUSE_EXITED)) - override fun mouseReleased(e: MouseEvent) { - mouse(swingMouse(e, MOUSE_RELEASED)) - onMouse(swingMouse(e, MOUSE_RELEASED)) - } - - override fun mousePressed(e: MouseEvent) { - mouse(swingMouse(e, MOUSE_PRESSED)) - onMouse(swingMouse(e, MOUSE_PRESSED)) - } - }) - - addWindowListener(object : WindowListener { - override fun windowDeiconified(e: WindowEvent) = Unit - override fun windowActivated(e: WindowEvent) { - loseFocus = false - FClock.resume() - onFocus() - } - - override fun windowDeactivated(e: WindowEvent) { - loseFocus = true - FClock.pause() - onLoseFocus() - } - - override fun windowIconified(e: WindowEvent) = Unit - override fun windowClosing(e: WindowEvent) = onExit() - override fun windowClosed(e: WindowEvent) = Unit - override fun windowOpened(e: WindowEvent) = Unit - }) + @JvmOverloads + fun webResource( + url: String, + submit: (String) -> Unit, + default: String = "DEFAULT_VALUE") { + var ret = "" + doAsync { + ret = readString(default) + uiThread { submit(ret) } } - - override fun update(g: Graphics?) = paint(g) - override fun paintComponent(g: Graphics) { - clearScreen() - drawEverything(drawer) - - if (loseFocus and loseFocusChangeColor) { - repeat(drawer.friceImage.width) { x: Int -> - repeat(drawer.friceImage.height) { y: Int -> - drawer.friceImage[x, y] = drawer.friceImage[x, y].darker() - } - } + doAsync { + if (ret != "DEFAULT_VALUE" && !isNetConnected) { + uiThread { submit(ret) } + } else { + ret = URL(url).readText(Charsets.UTF_8) + uiThread { submit(ret) } + save(url, ret) } + } + } + + override val screenCut get() = DroidImage(canvas.drawingCache) - drawer.restore() - drawer.init() - drawer.color = ColorResource.DARK_GRAY - if (showFPS) drawer.drawString("fps: ${fpsCounter.display}", 30.0, height - 30.0) + inner class FriceCanvas : View(this) { + init { + setOnClickListener { + mouse(OnMouseEvent(it.x.toDouble(), it.y.toDouble(), MOUSE_CLICKED)) + onMouse(OnMouseEvent(it.x.toDouble(), it.y.toDouble(), MOUSE_CLICKED)) + } + setOnTouchListener { _, it -> + mouse(OnMouseEvent(it.x.toDouble(), it.y.toDouble(), MOUSE_PRESSED)) + onMouse(OnMouseEvent(it.x.toDouble(), it.y.toDouble(), MOUSE_PRESSED)) + return@setOnTouchListener false + } + } - /* - * 厚颜无耻 - * drawer.drawString("Powered by FriceEngine. ice1000", 5, 20) - */ - g.drawImage(drawer.friceImage.image, 0, 0, this) + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + @SuppressLint("DrawAllocation") + val localDrawer = drawer ?: DroidDrawer(canvas).also { drawer = it } + localDrawer.canvas = canvas + clearScreen(localDrawer) + drawEverything(localDrawer) + +// if (loseFocus and loseFocusChangeColor) { +// repeat(localDrawer.canvas.width) { x: Int -> +// repeat(localDrawer.canvas.height) { y: Int -> +// localDrawer.canvas[x, y] = drawer.friceImage[x, y].darker() +// } +// } +// } + + localDrawer.restore() + localDrawer.init() + localDrawer.color = ColorResource.DARK_GRAY + if (showFPS) localDrawer.drawString("fps: ${fpsCounter.display}", 30.0, height - 30.0) } } - } diff --git a/frice/src/main/kotlin/org/frice/android/OldGame.kt b/frice/src/main/kotlin/org/frice/android/OldGame.kt deleted file mode 100644 index fdd17fe..0000000 --- a/frice/src/main/kotlin/org/frice/android/OldGame.kt +++ /dev/null @@ -1,380 +0,0 @@ -package org.frice.android - -import android.content.Context -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.RectF -import android.os.Bundle -import android.support.v7.app.AppCompatActivity -import android.view.MotionEvent -import android.view.View -import org.frice.android.obj.AbstractObject -import org.frice.android.obj.FObject -import org.frice.android.obj.PhysicalObject -import org.frice.android.obj.button.FButton -import org.frice.android.obj.button.FText -import org.frice.android.obj.button.SimpleButton -import org.frice.android.obj.effects.LineEffect -import org.frice.android.resource.graphics.ColorResource -import org.frice.android.utils.graphics.shape.FOval -import org.frice.android.utils.graphics.shape.FRectangle -import org.frice.android.utils.message.error.FatalError -import org.frice.utils.message.FLog -import org.frice.game.obj.sub.ShapeObject -import org.frice.game.resource.FResource -import org.frice.game.utils.misc.forceRun -import org.frice.game.utils.misc.loopIf -import org.frice.game.utils.time.FTimeListener -import org.frice.game.utils.time.FTimer -import java.util.* -import kotlin.concurrent.thread - - -/** - * First game class(not for you) - * - * Standard library, mainly for GUI. - * some other library is in @see - * The base game class. - * this class do rendering, and something which are invisible to - * game developer. - * - * Created by ice1000 on 2016/10/6. - * @author ice1000 - */ -open class OldGame : AppCompatActivity() { - - protected @JvmField val objects = LinkedList() - protected @JvmField val objectDeleteBuffer = ArrayList() - protected @JvmField val objectAddBuffer = ArrayList() - - protected @JvmField val timeListeners = LinkedList() - protected @JvmField val timeListenerDeleteBuffer = ArrayList() - protected @JvmField val timeListenerAddBuffer = ArrayList() - - protected @JvmField val texts = LinkedList() - protected @JvmField val textDeleteBuffer = ArrayList() - protected @JvmField val textAddBuffer = ArrayList() - - /** - * if paused, main window will not call `onRefresh()`. - */ - var paused = false - - /** - * not implemented yet. - * currently it's same as paused. - */ - var stopped = false - - /** - * background resource (don't setBackground, please use `setBack()` instead.) - */ - var back: FResource = ColorResource.BLACK - var debug = true - - /** - * a general purpose instance for generating random numbers - */ - val random = Random() - - /** - * if true, the engine will collect all objects which are invisible from game window. - */ - var autoGC = true - - /** - * if true, there will be a fps calculating on the bottom-left side of window. - */ - var showFPS = true - - var loseFocus = false - protected set - - var loseFocusChangeColor = true - - private val refresh = FTimer(30) - - private var fpsCounter = 0 - private var fpsDisplay = 0 - private lateinit var fpsTimer: FTimer - - private lateinit var canvas: FriceCanvas - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - canvas = FriceCanvas(this) - fpsTimer = FTimer(1000) - setContentView(canvas) - onInit() - thread { - FLog.v("Engine start!") - loopIf(!paused && !stopped && refresh.ended()) { - forceRun { - onRefresh() - timeListeners.forEach { it.check() } - canvas.invalidate() - ++fpsCounter - if (fpsTimer.ended()) { - fpsDisplay = fpsCounter - fpsCounter = 0 - } - } - } - } - } - - protected open fun onInit() = Unit - protected open fun onRefresh() = Unit - protected open fun onClick() = Unit - protected open fun onTouch(event: MotionEvent) = Unit - protected open fun customDraw(canvas: Canvas) = Unit - - /** - * adds objects - * - * @param objs as a collection - */ - infix fun addObjects(objs: Collection) = addObjects(objs.toTypedArray()) - - /** - * adds objects - * - * @param objs as an array - */ - infix fun addObjects(objs: Array) = objs.forEach { o -> addObject(o) } - - /** - * adds an object to game, to be shown on game window. - */ - infix fun addObject(obj: AbstractObject) { - if (obj is FText) textAddBuffer.add(obj) - else objectAddBuffer.add(obj) - } - - /** - * clears all objects. - * this method is safe. - */ - fun clearObjects() { - objectDeleteBuffer.addAll(objects) - textDeleteBuffer.addAll(texts) - } - - - /** - * removes objects. - * this method is safe. - * - * @param objs will remove objects which is equal to them, as an array. - */ - infix fun removeObjects(objs: Array) = objs.forEach { o -> objectDeleteBuffer.add(o) } - - /** - * removes objects. - * this method is safe. - * - * @param objs will remove objects which is equal to them, as a collection. - */ - infix fun removeObjects(objs: Collection) = removeObjects(objs.toTypedArray()) - - /** - * removes single object. - * this method is safe. - * - * @param obj will remove objects which is equal to it. - */ - infix fun removeObject(obj: AbstractObject) { - if (obj is FText) textDeleteBuffer.add(obj) - else objectDeleteBuffer.add(obj) - } - - /** - * adds a auto-executed time listener - * you must add or it won't work. - */ - infix fun addTimeListener(listener: FTimeListener) = timeListenerAddBuffer.add(listener) - - /** - * adds an array of auto-executed time listeners - */ - infix fun addTimeListeners(listeners: Array) = listeners.forEach { l -> addTimeListener(l) } - - /** - * adds a collection of auto-executed time listeners - */ - infix fun addTimeListeners(listeners: Collection) = addTimeListeners(listeners.toTypedArray()) - - /** - * removes all auto-executed time listeners - */ - fun clearTimeListeners() = timeListenerDeleteBuffer.addAll(timeListeners) - - /** - * removes auto-executed time listeners specified in the given array. - * - * @param listeners the array - */ - infix fun removeTimeListeners(listeners: Array) = - listeners.forEach { l -> removeTimeListener(l) } - - /** - * auto-execute time listeners which are equal to the given collection. - * - * @param listeners the collection - */ - infix fun removeTimeListeners(listeners: Collection) = removeTimeListeners(listeners.toTypedArray()) - - /** - * removes specified listener - * - * @param listener the listener - */ - infix fun removeTimeListener(listener: FTimeListener) = timeListenerDeleteBuffer.add(listener) - - /** - * do the delete and add work, to prevent Exceptions - */ - private fun processBuffer() { - objects.addAll(objectAddBuffer) - objects.removeAll(objectDeleteBuffer) - objectDeleteBuffer.clear() - objectAddBuffer.clear() - - timeListeners.addAll(timeListenerAddBuffer) - timeListeners.removeAll(timeListenerDeleteBuffer) - timeListenerDeleteBuffer.clear() - timeListenerAddBuffer.clear() - - texts.addAll(textAddBuffer) - texts.removeAll(textDeleteBuffer) - textDeleteBuffer.clear() - textAddBuffer.clear() - } - - /** - * must be used in Game - */ - inner class FriceCanvas(context: Context) : View(context) { - - init { - if (context !is Game) throw FatalError() - setOnClickListener { - context.onClick() - } - setOnTouchListener { view, motionEvent -> - context.onTouch(motionEvent) - return@setOnTouchListener false - } - } - - val p = Paint().apply { - isAntiAlias = true - style = Paint.Style.FILL - } - - private fun Paint.reset() { - color = ColorResource.GRAY.color - } - - override fun onDraw(canvas: Canvas?) { - super.onDraw(canvas) - processBuffer() - canvas?.save() - - objects.forEach { o -> - if (o is FObject) { - o.runAnims() - o.checkCollision() - } - } - - canvas?.let { - objects.forEach { o -> - - canvas.restore() - p.reset() - - if (autoGC && (o.x.toInt() < -width || - o.x.toInt() > width + width || - o.y.toInt() < -height || - o.y.toInt() > height + height)) { - if (o is PhysicalObject) o.died = true - removeObject(o) - } - - if (o is PhysicalObject) canvas.rotate(o.rotate.toFloat(), - (o.x + o.width / 2).toFloat(), (o.y + o.height / 2).toFloat()) - else canvas.rotate(o.rotate.toFloat(), o.x.toFloat(), o.y.toFloat()) - when (o) { - is FObject.ImageOwner -> - canvas.drawBitmap(o.image, o.x.toFloat(), o.y.toFloat(), p) - is ShapeObject -> { - p.color = o.getResource().color - when (o.collideBox) { - is FRectangle -> canvas.drawRect( - o.x.toFloat(), - o.y.toFloat(), - o.width.toFloat(), - o.height.toFloat(), - p - ) - is FOval -> canvas.drawOval( - RectF( - o.x.toFloat(), - o.y.toFloat(), - o.width.toFloat(), - o.height.toFloat() - ), - p - ) - } - } - is LineEffect -> { - p.color = o.colorResource.color - canvas.drawLine( - o.x.toFloat(), - o.y.toFloat(), - o.x2.toFloat(), - o.y2.toFloat(), - p - ) - } - } - - texts.forEach { b -> - - canvas.restore() - p.reset() - - if (b is FButton) { - p.color = b.getColor().color - when (b) { - is FObject.ImageOwner -> - canvas.drawBitmap(b.image, b.x.toFloat(), b.y.toFloat(), p) - is SimpleButton -> { - p.color = b.getColor().color - canvas.drawRoundRect( - RectF( - b.x.toFloat(), - b.y.toFloat(), - b.width.toFloat(), - b.height.toFloat() - ), - Math.min((b.width * 0.5).toFloat(), 10F), - Math.min((b.height * 0.5).toFloat(), 10F), p) - p.color = ColorResource.GRAY.color - canvas.drawText(b.text, b.x.toFloat(), b.y.toFloat(), p) - } - } - } else canvas.drawText(b.text, b.x.toFloat(), b.y.toFloat(), p) - } - } - - if (showFPS) canvas.drawText("fps: $fpsDisplay", 30F, height - 30F, p) - - customDraw(canvas) - } - } - } -} diff --git a/frice/src/main/kotlin/org/frice/obj/button/Texts.kt b/frice/src/main/kotlin/org/frice/obj/button/Texts.kt index ae92ddf..5b649f9 100644 --- a/frice/src/main/kotlin/org/frice/obj/button/Texts.kt +++ b/frice/src/main/kotlin/org/frice/obj/button/Texts.kt @@ -13,22 +13,9 @@ import org.frice.resource.graphics.ColorResource.Companion.DARK_GRAY abstract class FText : AbstractObject { open var text = "" open var textSize: Double = 16.0 - set(value) { - field = value - fonttmpobj = null - } - - open var fontName = "Consolas" - set(value) { - field = value - fonttmpobj = null - } override var rotate = 0.0 abstract val color: ColorResource - - @Suppress("PropertyName") - @JvmField internal var fonttmpobj: Any? = null } /** diff --git a/frice/src/main/kotlin/org/frice/platform/FriceDrawer.kt b/frice/src/main/kotlin/org/frice/platform/FriceDrawer.kt index 329ad56..ccfcae3 100644 --- a/frice/src/main/kotlin/org/frice/platform/FriceDrawer.kt +++ b/frice/src/main/kotlin/org/frice/platform/FriceDrawer.kt @@ -18,7 +18,7 @@ interface FriceDrawer { fun drawLine(x: Double, y: Double, width: Double, height: Double) fun drawRoundRect(x: Double, y: Double, width: Double, height: Double, arcWidth: Double, arcHeight: Double) fun stringSize(size: Double) - fun useFont(text: FText) + // fun useFont(text: FText) fun rotate(theta: Double, x: Double, y: Double) fun restore() fun strokeOval(x: Double, y: Double, width: Double, height: Double) diff --git a/frice/src/main/kotlin/org/frice/platform/FriceGame.kt b/frice/src/main/kotlin/org/frice/platform/FriceGame.kt index b9e4e51..0cedc9d 100644 --- a/frice/src/main/kotlin/org/frice/platform/FriceGame.kt +++ b/frice/src/main/kotlin/org/frice/platform/FriceGame.kt @@ -4,13 +4,10 @@ import org.frice.event.OnMouseEvent import org.frice.obj.* import org.frice.obj.button.* import org.frice.obj.effects.LineEffect -import org.frice.obj.sub.ImageObject import org.frice.obj.sub.ShapeObject import org.frice.platform.adapter.DroidImage -import org.frice.platform.owners.Resizable import org.frice.platform.owners.Sized import org.frice.resource.graphics.ColorResource -import org.frice.resource.image.ImageResource import org.frice.utils.shape.* /** @@ -18,10 +15,9 @@ import org.frice.utils.shape.* * @since v1.2 * @param Drawer the FriceDrawer used */ -interface FriceGame - : Sized, Resizable, Collidable { +interface FriceGame + : Sized, Collidable { val layers: Array - val drawer: Drawer override val box get() = object : FShapeQuad { @@ -47,8 +43,6 @@ interface FriceGame var loseFocusChangeColor: Boolean var millisToRefresh: Int var paused: Boolean - var isFullScreen: Boolean - var isAlwaysTop: Boolean /** do the delete and add work, to prevent Exceptions */ fun processBuffer() = layers.forEach(Layer::processBuffer) @@ -116,7 +110,7 @@ interface FriceGame /** remove objects unsafely using vararg */ fun instantRemoveObject(vararg objs: AbstractObject) = instantRemoveObject(0, *objs) - fun clearScreen() { + fun clearScreen(drawer: Drawer) { drawer.color = ColorResource.WHITE drawer.drawRect(0.0, 0.0, width.toDouble(), height.toDouble()) drawer.restore() @@ -174,7 +168,6 @@ interface FriceGame restore() init() // TODO rotate(b.rotate) - useFont(b) } if (b is FButton) { when (b) { @@ -200,11 +193,6 @@ interface FriceGame customDraw(bgg) } - fun setCursor(o: FriceImage) - - fun setCursor(o: ImageObject) = setCursor(o.image) - fun setCursor(o: ImageResource) = setCursor(o.image) - /** * get a screenShot. * diff --git a/frice/src/main/kotlin/org/frice/platform/adapter/DroidDrawer.kt b/frice/src/main/kotlin/org/frice/platform/adapter/DroidDrawer.kt index b74ce1a..490af96 100644 --- a/frice/src/main/kotlin/org/frice/platform/adapter/DroidDrawer.kt +++ b/frice/src/main/kotlin/org/frice/platform/adapter/DroidDrawer.kt @@ -1,87 +1,101 @@ package org.frice.platform.adapter -import android.graphics.Canvas -import org.frice.obj.button.FText +import android.graphics.* import org.frice.platform.FriceDrawer import org.frice.platform.FriceImage import org.frice.resource.graphics.ColorResource import org.frice.utils.cast -import org.frice.utils.forceRun /** * Created by ice1000 on 2016/10/31. * * @author ice1000 */ -class DroidDrawer(private val canvas: Canvas) : FriceDrawer { +class DroidDrawer(var canvas: Canvas) : FriceDrawer { + constructor(bitmap: Bitmap) : this(Canvas(bitmap)) + + val paint = Paint() override fun init() { - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) - forceRun { g.font = Font("Consolas", Font.PLAIN, 16) } + canvas.save() } - val friceImage = DroidImage(canvas.width, canvas.height) + private val rectF = RectF() + override var color: ColorResource - get() = ColorResource(g.color) + get() = ColorResource(paint.color) set(value) { - g.color = value.`get-color`() + paint.color = value.color } - var g: Graphics2D = cast(friceImage.image.graphics) + val g = canvas override fun stringSize(size: Double) { - g.font = g.font.deriveFont(size.toFloat()) + paint.textSize = size.toFloat() } - override fun useFont(text: FText) { - if (text.fonttmpobj == null) text.fonttmpobj = Font(text.fontName, Font.PLAIN, text.textSize.toInt()) - if (g.font != text.fonttmpobj) - g.font = cast(text.fonttmpobj) + override fun drawOval(x: Double, y: Double, width: Double, height: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.FILL + g.drawOval(rectF, paint) } - override fun drawOval(x: Double, y: Double, width: Double, height: Double) = - g.fillOval(x.toInt(), y.toInt(), width.toInt(), height.toInt()) - - override fun strokeOval(x: Double, y: Double, width: Double, height: Double) = - g.fillOval(x.toInt(), y.toInt(), width.toInt(), height.toInt()) + override fun strokeOval(x: Double, y: Double, width: Double, height: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.STROKE + g.drawOval(rectF, paint) + } - override fun drawString(string: String, x: Double, y: Double) = - g.drawString(string, x.toInt(), y.toInt()) + override fun drawString(string: String, x: Double, y: Double) { + g.drawText(string, x.toFloat(), y.toFloat(), paint) + } override fun drawImage(image: FriceImage, x: Double, y: Double) { - g.drawImage(cast(image).image, x.toInt(), y.toInt(), canvas) + g.drawBitmap(cast(image).image, x.toFloat(), y.toFloat(), paint) } - override fun drawRect(x: Double, y: Double, width: Double, height: Double) = - g.fillRect(x.toInt(), y.toInt(), width.toInt(), height.toInt()) + override fun drawRect(x: Double, y: Double, width: Double, height: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.FILL + g.drawRect(rectF, paint) + } - override fun strokeRect(x: Double, y: Double, width: Double, height: Double) = - g.drawRect(x.toInt(), y.toInt(), width.toInt(), height.toInt()) + override fun strokeRect(x: Double, y: Double, width: Double, height: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.STROKE + g.drawRect(rectF, paint) + } override fun drawLine(x: Double, y: Double, width: Double, height: Double) = - g.drawLine(x.toInt(), y.toInt(), width.toInt(), height.toInt()) + g.drawLine(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), paint) - override fun rotate(theta: Double, x: Double, y: Double) = g.rotate(theta, x, y) + override fun rotate(theta: Double, x: Double, y: Double) = g.rotate(theta.toFloat(), x.toFloat(), y.toFloat()) override fun drawRoundRect( - x: Double, - y: Double, - width: Double, - height: Double, - arcWidth: Double, - arcHeight: Double) = - g.fillRoundRect(x.toInt(), y.toInt(), width.toInt(), height.toInt(), arcWidth.toInt(), arcHeight.toInt()) + x: Double, + y: Double, + width: Double, + height: Double, + arcWidth: Double, + arcHeight: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.FILL + g.drawRoundRect(rectF, arcWidth.toFloat(), arcHeight.toFloat(), paint) + } override fun strokeRoundRect( - x: Double, - y: Double, - width: Double, - height: Double, - arcWidth: Double, - arcHeight: Double) = - g.drawRoundRect(x.toInt(), y.toInt(), width.toInt(), height.toInt(), arcWidth.toInt(), arcHeight.toInt()) + x: Double, + y: Double, + width: Double, + height: Double, + arcWidth: Double, + arcHeight: Double) { + rectF.set(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) + paint.style = Paint.Style.STROKE + g.drawRoundRect(rectF, arcWidth.toFloat(), arcHeight.toFloat(), paint) + } override fun restore() { - g = cast(friceImage.image.graphics) + canvas.restore() } } \ No newline at end of file diff --git a/frice/src/main/kotlin/org/frice/platform/adapter/DroidImage.kt b/frice/src/main/kotlin/org/frice/platform/adapter/DroidImage.kt index 41786a2..83411f7 100644 --- a/frice/src/main/kotlin/org/frice/platform/adapter/DroidImage.kt +++ b/frice/src/main/kotlin/org/frice/platform/adapter/DroidImage.kt @@ -13,20 +13,20 @@ open class DroidImage(val image: Bitmap) : FriceImage { override operator fun get(x: Int, y: Int) = ColorResource(image.getPixel(x, y)) override operator fun set(x: Int, y: Int, color: Int) = image.setPixel(x, y, color) - override fun scale(x: Double, y: Double) = DroidImage(scaleImpl(x, y)) - protected fun scaleImpl(x: Double, y: Double): Bitmap = AffineTransformOp( - AffineTransform().apply { scale(x, y) }, - AffineTransformOp.TYPE_BILINEAR).filter(image, null) + override fun scale(x: Double, y: Double) = TODO() // DroidImage(scaleImpl(x, y)) +// protected fun scaleImpl(x: Double, y: Double): Bitmap = AffineTransformOp( +// AffineTransform().apply { scale(x, y) }, +// AffineTransformOp.TYPE_BILINEAR).filter(image, null) override fun part(x: Int, y: Int, width: Int, height: Int) = DroidImage(Bitmap.createBitmap(image, x, y, width, height)) override fun clone() = DroidImage(image.copy(image.config, true)) - override fun flip(orientation: Boolean) = DroidImage(flipImpl(orientation)) - protected fun flipImpl(orientation: Boolean): BufferedImage = AffineTransformOp( - if (orientation) AffineTransform.getScaleInstance(-1.0, 1.0).apply { translate((-width).toDouble(), 0.0) } // horizontal - else AffineTransform.getScaleInstance(1.0, -1.0).apply { translate(0.0, (-height).toDouble()) }, // vertical - AffineTransformOp.TYPE_NEAREST_NEIGHBOR).filter(image, null) + override fun flip(orientation: Boolean) = TODO() // DroidImage(flipImpl(orientation)) +// protected fun flipImpl(orientation: Boolean): BufferedImage = AffineTransformOp( +// if (orientation) AffineTransform.getScaleInstance(-1.0, 1.0).apply { translate((-width).toDouble(), 0.0) } // horizontal +// else AffineTransform.getScaleInstance(1.0, -1.0).apply { translate(0.0, (-height).toDouble()) }, // vertical +// AffineTransformOp.TYPE_NEAREST_NEIGHBOR).filter(image, null) fun greenify() = image.greenify() fun redify() = image.redify() diff --git a/frice/src/main/kotlin/org/frice/platform/adapter/JvmImage.kt b/frice/src/main/kotlin/org/frice/platform/adapter/JvmImage.kt new file mode 100644 index 0000000..7aaf99c --- /dev/null +++ b/frice/src/main/kotlin/org/frice/platform/adapter/JvmImage.kt @@ -0,0 +1,45 @@ +package org.frice.platform.adapter + +import org.frice.platform.FriceImage +import org.frice.resource.graphics.ColorResource +import org.frice.utils.* +import java.awt.geom.AffineTransform +import java.awt.image.AffineTransformOp +import java.awt.image.BufferedImage + +open class JvmImage(val image: BufferedImage) : FriceImage { + constructor(width: Int, height: Int) : this(BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)) + + override val width = image.width + override val height = image.height + override operator fun get(x: Int, y: Int) = ColorResource(image.getRGB(x, y)) + override operator fun set(x: Int, y: Int, color: Int) = image.setRGB(x, y, color) + + override fun scale(x: Double, y: Double) = JvmImage(scaleImpl(x, y)) + protected fun scaleImpl(x: Double, y: Double): BufferedImage = AffineTransformOp( + AffineTransform().apply { scale(x, y) }, + AffineTransformOp.TYPE_BILINEAR).filter(image, null) + + override fun part(x: Int, y: Int, width: Int, height: Int) = JvmImage(partImpl(x, y, width, height)) + protected fun partImpl(x: Int, y: Int, width: Int, height: Int): BufferedImage + = image.getSubimage(x, y, width, height) + + override fun clone() = JvmImage(cloneImpl()) + protected fun cloneImpl() = BufferedImage(width, height, image.type).apply { + this@apply.data = this@JvmImage.image.data + } + + override fun flip(orientation: Boolean) = JvmImage(flipImpl(orientation)) + protected fun flipImpl(orientation: Boolean): BufferedImage = AffineTransformOp( + if (orientation) AffineTransform.getScaleInstance(-1.0, 1.0).apply { translate((-width).toDouble(), 0.0) } // horizontal + else AffineTransform.getScaleInstance(1.0, -1.0).apply { translate(0.0, (-height).toDouble()) }, // vertical + AffineTransformOp.TYPE_NEAREST_NEIGHBOR).filter(image, null) + + override fun fx() = JfxImage(image) + + fun greenify() = image.greenify() + fun redify() = image.redify() + fun bluify() = image.bluify() +} + + diff --git a/frice/src/main/kotlin/org/frice/platform/owners/Resizable.java b/frice/src/main/kotlin/org/frice/platform/owners/Resizable.java deleted file mode 100644 index 593a2e3..0000000 --- a/frice/src/main/kotlin/org/frice/platform/owners/Resizable.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.frice.platform.owners; - -public interface Resizable { - void setResizable(boolean resizable); - - boolean isResizable(); -} diff --git a/frice/src/main/kotlin/org/frice/platform/owners/TitleOwner.java b/frice/src/main/kotlin/org/frice/platform/owners/TitleOwner.java deleted file mode 100644 index 19a7497..0000000 --- a/frice/src/main/kotlin/org/frice/platform/owners/TitleOwner.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.frice.platform.owners; - -import org.jetbrains.annotations.NotNull; - -public interface TitleOwner { - void setTitle(@NotNull String title); - - @NotNull String getTitle(); -} diff --git a/frice/src/main/kotlin/org/frice/resource/image/ImageResource.kt b/frice/src/main/kotlin/org/frice/resource/image/ImageResource.kt index 30a974f..b90a0dd 100644 --- a/frice/src/main/kotlin/org/frice/resource/image/ImageResource.kt +++ b/frice/src/main/kotlin/org/frice/resource/image/ImageResource.kt @@ -1,7 +1,6 @@ package org.frice.resource.image import org.frice.platform.FriceImage -import org.frice.platform.adapter.JfxImage import org.frice.platform.adapter.DroidImage import org.frice.resource.FResource @@ -29,9 +28,6 @@ abstract class ImageResource : FResource { @JvmStatic fun empty() = create(DroidImage(1, 1)) - - @JvmStatic - fun emptyFX() = create(JfxImage(1, 1)) } abstract var image: FriceImage diff --git a/frice/src/main/kotlin/org/frice/utils/IOUtils.kt b/frice/src/main/kotlin/org/frice/utils/IOUtils.kt deleted file mode 100644 index bae9234..0000000 --- a/frice/src/main/kotlin/org/frice/utils/IOUtils.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.frice.utils - -import android.content.Context -import android.content.Intent -import android.net.* -import org.frice.Game -import org.frice.utils.data.readString -import org.frice.utils.data.save -import org.jetbrains.anko.doAsync -import org.jetbrains.anko.uiThread -import java.net.URL - -/** - * Created by ice1000 on 2016/10/8. - * - * @author ice1000 - */ -fun Game.openWeb(url: String) = startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) - -/** - * if this value is null, - * it means I have 2 load data from Sp. - */ -val Context.haveNetwork: Boolean - get() = connection != null && connection!!.isConnected - -private val Context.connection: NetworkInfo? - get() = (getSystemService(Context.CONNECTIVITY_SERVICE) - as ConnectivityManager).activeNetworkInfo - - -const val DEFAULT_VALUE = "DEFAULT_VALUE" - -/** - * this will cache the data into SharedPreference - * next time when the network is invalid, it will return the data - * stored in the SharedPreference. - * - * this method extended String. - */ -fun Context.webResource( - url: String, - submit: (String) -> Unit, - default: String = DEFAULT_VALUE) { - var ret = "" - doAsync { - ret = readString(default) - uiThread { submit(ret) } - } - doAsync { - if (ret != DEFAULT_VALUE && !haveNetwork) { - uiThread { submit(ret) } - } else { - ret = URL(url).readText(Charsets.UTF_8) - uiThread { submit(ret) } - save(url, ret) - } - } -} - -