Mercurial > hg > charamega
view src/net/kryshen/charamega/field.mirah @ 6:9d940c7ee4c0
Adjusted defaults and limits.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Mon, 16 Jul 2012 06:30:28 +0400 |
parents | 1e64a109812f |
children | 2efb0973ab83 |
line wrap: on
line source
# # Copyright 2012 Mikhail Kryshen <mikhail@kryshen.net> # # This file is part of Charamega. # # Charamega is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Charamega is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Charamega. If not, see <http://www.gnu.org/licenses/>. # package net.kryshen.charamega import java.awt.* import java.awt.geom.* import java.awt.event.* import javax.swing.* import java.util.List class Field < JComponent def initialize(game:Game) @field_color = Color.WHITE @border_color = Color.GRAY @active_border_color = Color.DARK_GRAY @symbol_color = Color.BLACK @back_color = Color.LIGHT_GRAY @face_color = Color.new(0xFFFDDD) @game = game setOpaque true setDoubleBuffered true setPreferredSize Dimension.new(790, 500) begin source = getClass.getResource("DejaVuSans.ttf").openStream font = Font.createFont(Font.TRUETYPE_FONT, source) ensure source.close unless source.nil? end setFont font enableEvents AWTEvent.MOUSE_EVENT_MASK enableEvents AWTEvent.MOUSE_MOTION_EVENT_MASK end def processMouseEvent(event) if isEnabled if event.getID == MouseEvent.MOUSE_PRESSED @hold = hit(event.getX, event.getY) elsif event.getID == MouseEvent.MOUSE_RELEASED and !@hold.nil? and @hold == hit(event.getX, event.getY) @game.open @hold repaint elsif event.getID == MouseEvent.MOUSE_EXITED and !@hovered.nil? @hovered = nil repaint end end super end def processMouseMotionEvent(event) if isEnabled h = hit(event.getX, event.getY) if event.getID == MouseEvent.MOUSE_DRAGGED if h == @hold and h != @hovered @hovered = h repaint end if h != @hold and @hold == @hovered @hovered = nil repaint end elsif h != @hovered @hovered = h repaint end end super end def paintComponent(g1) g = Graphics2D(g1) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON) w = getWidth h = getHeight g.setColor @field_color g.fillRect 0, 0, w, h insets = getInsets w -= insets.left + insets.right h -= insets.top + insets.bottom layout = @game.layout(w, h) time = System.nanoTime max_cols = Math.ceil(double(@game.cards.size) / layout.size) rh = double(h) / layout.size card_size = Math.min(rh, double(w) / max_cols) / 1.4 font_size = card_size font = g.getFont.deriveFont(float(font_size)) frc = g.getFontRenderContext rm_scale = 2.0 outer = Rectangle2D.Double.new inner = Rectangle2D.Double.new border = Path2D.Double.new(Path2D.WIND_EVEN_ODD) save_t = g.getTransform y = rh / 2 + insets.top layout.each do |row| cw = double(w) / List(row).size x = cw / 2 + insets.left List(row).each do |e| card = Card(e) v = card.visible_state(time) # Compute area potentially affected by the card. if v < 1.0 paint_x = int(Math.floor(x - cw * rm_scale / 2 - 1)) paint_y = int(Math.floor(y - rh * rm_scale / 2 - 1)) paint_w = int(Math.ceil(cw * rm_scale + 2)) paint_h = int(Math.ceil(rh * rm_scale + 2)) else paint_x = int(Math.floor(x - cw / 2 - 1)) paint_y = int(Math.floor(y - rh / 2 - 1)) paint_w = int(Math.ceil(cw + 2)) paint_h = int(Math.ceil(rh + 2)) end if v > 0.0 and g.hitClip(paint_x, paint_y, paint_w, paint_h) f = card.flip_state(time) if v < 1.0 or (f > -1.0 and f < 1.0) # Animation is in progress. repaint 30, paint_x, paint_y, paint_w, paint_h end g.translate x, y v_scale = rm_scale - Math.sqrt(v) * rm_scale g.scale Math.abs(f) + v_scale, 1.0 + v_scale g.rotate card.angle * v outer.setRect(-card_size / 2, -card_size / 2, card_size, card_size) inner.setRect(1 - card_size / 2, 1 - card_size / 2, card_size - 2, card_size - 2) border.reset border.append outer, false border.append inner, false if f > 0 g.setColor with_alpha(@face_color, v) else g.setColor with_alpha(@back_color, v) end g.fill inner if f > 0 g.setColor with_alpha(@symbol_color, Math.sqrt(v)) gv = font.createGlyphVector(frc, String.valueOf(card.symbol)) sb = gv.getVisualBounds # Scale down if the glyph does not fit. tolerance = 0.95 scale = Math.min(inner.getWidth * tolerance / sb.getWidth, inner.getHeight * tolerance / sb.getHeight) save_t_2 = g.getTransform g.scale scale, scale if scale < 1.0 g.drawGlyphVector(gv, -float(sb.getX + sb.getWidth / 2), -float(sb.getY + sb.getHeight / 2)) g.setTransform save_t_2 end if card == @hovered g.setColor with_alpha(@active_border_color, v) else g.setColor with_alpha(@border_color, v) end g.fill border g.setTransform save_t end x += cw end y += rh end end private def hit(x:int, y:int) insets = getInsets size = getSize @game.hit(x - insets.left, y - insets.top, size.width - insets.left - insets.right, size.height - insets.top - insets.bottom) end def with_alpha(c:Color, alpha:double) Color.new c.getRed, c.getGreen, c.getBlue, int(alpha * 255) end end